realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 04.10.04 07:25
Оценка:
Пишу под VC++6.
Пользуюсь стандартными функциями malloc и realloc.
Типа того:

unsigned long *begin;
int len=1;
...
begin=(unsigned long*)malloc(sizeof(unsigned long));
...
что-то делаю с этим лонгом...
if(надо еще места в памяти)
{ len++;
begin=(unsigned long*)realloc(begin, len*sizeof(unsigned long));
}
...
короче по мере надобности увеличиваем память на unsigned long каждый раз. Но это не всегда работает верно. Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.
Кто с этим сталкивался и как боролся?
Re: realloc неправильно выделяет память...
От: bkat  
Дата: 04.10.04 07:36
Оценка:
Здравствуйте, Звероящер, Вы писали:

З>Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.


Откуда такая уверенность про используемую память?
Re: realloc неправильно выделяет память...
От: Аноним  
Дата: 04.10.04 07:41
Оценка:
Здравствуйте, Звероящер, Вы писали:

Проверяешь ли ты возвращаемое значение при вызовах malloc и realloc?
Re: realloc неправильно выделяет память...
От: Astaroth Россия  
Дата: 04.10.04 07:42
Оценка:
Здравствуйте, Звероящер, Вы писали:

З> begin=(unsigned long*)realloc(begin, len*sizeof(unsigned long));


Как насчёт выделять сразу помногу?
У std::vector такая стратегия: если есть n байт, и ты не вписываешься, то выделяется 2n байт
WinAmp играет: (умолк пока)
http://livejournal.com/users/breqwas
Re[2]: realloc неправильно выделяет память...
От: Аноним  
Дата: 04.10.04 09:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Звероящер, Вы писали:


А>Проверяешь ли ты возвращаемое значение при вызовах malloc и realloc?

Сравниваешь ли begin и NULL?
Re[2]: realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 04.10.04 09:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Звероящер, Вы писали:


А>Проверяешь ли ты возвращаемое значение при вызовах malloc и realloc?


Да. Во всех случаях не NULL
Re[2]: realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 04.10.04 09:48
Оценка:
Здравствуйте, bkat, Вы писали:

B>Здравствуйте, Звероящер, Вы писали:


З>>Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.


B>Откуда такая уверенность про используемую память?


Это видно из дебаггера... Неинциализированная память выглядит отлично от упорядоченой и потом, когда я пишу в эту память, все сбоит.
Re[3]: realloc неправильно выделяет память...
От: Аноним  
Дата: 04.10.04 12:03
Оценка:
Здравствуйте, Звероящер, Вы писали:

Приведи пример кода, который демонстрирует неправильную работу realloc (например падает при запуске).
Re: realloc неправильно выделяет память...
От: _Winnie Россия C++.freerun
Дата: 04.10.04 12:21
Оценка:
Здравствуйте, Звероящер, Вы писали:

З>короче по мере надобности увеличиваем память на unsigned long каждый раз. Но это не всегда работает верно. Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.

З>Кто с этим сталкивался и как боролся?

А надо ли с этим бороться? realloc имеет право выделить память на том же месте.
Если же он выделил память в другом месте, то ты не имеешь права обращаться к предыдущей, кстати.

>realloc неправильно выделяет память...

он не выделяет, он перевыделяет. И копирует (если выделил на новом месте).

Может, лучше воспользоваться std::vector? все-таки VC++6.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[4]: realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 05.10.04 07:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Звероящер, Вы писали:


А>Приведи пример кода, который демонстрирует неправильную работу realloc (например падает при запуске).


Вот та функция

unsigned long *inputvalue(int *len)
{ char num[]="0123456789";
char c;
int i,j,k;
unsigned long *begin, cnt;

*len=1;
begin=(unsigned long*)malloc((*len)*sizeof(unsigned long));
*begin=0; i=0;

while((c=getch())!=13)
{ for(j=0; j<(sizeof(num)/sizeof(num[0])); j++)
{ if(c==num[j])
{ printf("%c", c);
cnt=c&0x0F;
if(i>7)
{ (*len)+=1;
begin=(unsigned long*)realloc(begin,(*len)*sizeof(unsigned long));
*(begin+(*len-1))=0; i=0;
}
*(begin+(*len-1))<<=4;
*(begin+(*len-1))|=cnt;
i++;
}
}
}
return(begin);
}
Re[5]: realloc неправильно выделяет память...
От: yeti Россия  
Дата: 05.10.04 08:51
Оценка:
Здравствуйте, Звероящер, Вы писали:

З>Вот та функция

З>[...]

я так понял что это перевод десятичного числа в двоично-десятичное только байты в другом порядке?
в любом случае переписал нормально; у меня (VC6 и VC8) работает, как впрочем и ваш вариант.
вы уверены что проблема именно в этой функции, т.е. воспроизводится ли ошибка в пустом проекте, содержащем только её вызов?
вообще если проблема не исчезнет — покажите как вы её вызываете.

мой код:
unsigned long *inputvalue(int *dwords)
{
    unsigned long *data = NULL;
    int c, digits = 0;
    *dwords = 0;

    while( (c=getch()) != 13 )
    {
        if( ! isdigit(c) ) continue;
        printf("%c", c);
        c -= '0'; // '7' --> 7

        if(digits == 0)
        {
            ++*dwords;
            data = (unsigned long *)realloc(data, *dwords * sizeof(unsigned long));
            if( data == NULL )
            {
                fputs("error: out of memory\n", stderr);
                exit(13);
            }
            digits = sizeof(unsigned long) * (8 / 4); // 8 bits per byte, 4 bits per digit
            data[*dwords - 1] = 0;
        }

        data[*dwords - 1] <<= 4;
        data[*dwords - 1]  |= c;
        --digits;
    }

    puts("");
    return data;
}
... << RSDN@Home 1.1.4 beta 2 >>
Re[5]: realloc неправильно выделяет память...
От: Аноним  
Дата: 05.10.04 09:03
Оценка:
Здравствуйте, Звероящер, Вы писали:

З>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Звероящер, Вы писали:


А>>Приведи пример кода, который демонстрирует неправильную работу realloc (например падает при запуске).


З>Вот та функция


З>unsigned long *inputvalue(int *len)

skipped...

твой код не падает.
явных ошибок нет, точнее сказать не могу с назначением функции не разбирался
ниже код который тестирует реализацию realloc.
ошибок в реализации realloc он не выявил — запусти у себя — скажешь результат, или сам чего поймешь по коду.
предлагаю тебе переписать твою функцию, скорее всего realloc работает правильно, а ошибки у тебя в программе
и добавь пожалуй в свой код после realloc проверку if(begin==NULL) { printf("error : not enough memory"); }

int main(int argc, char* argv[])
{
    unsigned long* begin=(unsigned long*)malloc(sizeof(unsigned long));
    if(begin==NULL) {
        printf("error : begin==NULL (not enough memory)"); // такое поведение malloc оговорено в документации
        return -1;
    }
    for(unsigned long i=1;i<100000;++i) {
        begin[i-1]=i-1;
        unsigned long* begin_prev=begin;
        begin=(unsigned long*)realloc(begin,sizeof(unsigned long)*(i+1));
        if(begin_prev!=begin) {
            printf("memory moved. OK\n"); // такое поведение realloc оговорено в документации
        }
        if(begin==NULL) {
            printf("error : begin==NULL (not enough memory)"); // такое поведение realloc оговорено в документации
            return -1;
        }
        for(unsigned long j=0;j<i;j++) {
            if(begin[j]!=j) {
                printf("realloc doesn't work properly : begin[j]!=j"); // такого быть не может, иначе это ошибка в реализации realloc
                return -1;
            }
        }
    }
    printf("test passed successfully");

    return 0;
}
Re[6]: realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 05.10.04 10:18
Оценка:
Здравствуйте, yeti, Вы писали:

Y>Здравствуйте, Звероящер, Вы писали:


З>>Вот та функция

З>>[...]

Y>я так понял что это перевод десятичного числа в двоично-десятичное только байты в другом порядке?

Y>в любом случае переписал нормально; у меня (VC6 и VC8) работает, как впрочем и ваш вариант.
Y>вы уверены что проблема именно в этой функции, т.е. воспроизводится ли ошибка в пустом проекте, содержащем только её вызов?
Y>вообще если проблема не исчезнет — покажите как вы её вызываете.

Y>мой код:

Y>
Y>unsigned long *inputvalue(int *dwords)
Y>{
Y>    unsigned long *data = NULL;
Y>    int c, digits = 0;
Y>    *dwords = 0;

Y>    while( (c=getch()) != 13 )
Y>    {
Y>        if( ! isdigit(c) ) continue;
Y>        printf("%c", c);
Y>        c -= '0'; // '7' --> 7

Y>        if(digits == 0)
Y>        {
Y>            ++*dwords;
Y>            data = (unsigned long *)realloc(data, *dwords * sizeof(unsigned long));
Y>            if( data == NULL )
Y>            {
Y>                fputs("error: out of memory\n", stderr);
Y>                exit(13);
Y>            }
Y>            digits = sizeof(unsigned long) * (8 / 4); // 8 bits per byte, 4 bits per digit
Y>            data[*dwords - 1] = 0;
Y>        }

Y>        data[*dwords - 1] <<= 4;
Y>        data[*dwords - 1]  |= c;
Y>        --digits;
Y>    }

Y>    puts("");
Y>    return data;
Y>}
Y>



Да эта функция пакует десятичные цифры в тетрады. И если ввести этот realloc вызвается раз 10 (для установки длины unsigned long *10), то ошибка и вылазит...
Re[6]: realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 05.10.04 10:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Звероящер, Вы писали:


З>>Здравствуйте, Аноним, Вы писали:


А>>>Здравствуйте, Звероящер, Вы писали:


А>>>Приведи пример кода, который демонстрирует неправильную работу realloc (например падает при запуске).


З>>Вот та функция


З>>unsigned long *inputvalue(int *len)

А>skipped...

А>твой код не падает.

А>явных ошибок нет, точнее сказать не могу с назначением функции не разбирался
А>ниже код который тестирует реализацию realloc.
А>ошибок в реализации realloc он не выявил — запусти у себя — скажешь результат, или сам чего поймешь по коду.
А>предлагаю тебе переписать твою функцию, скорее всего realloc работает правильно, а ошибки у тебя в программе
А>и добавь пожалуй в свой код после realloc проверку if(begin==NULL) { printf("error : not enough memory"); }

А>
А>int main(int argc, char* argv[])
А>{
А>    unsigned long* begin=(unsigned long*)malloc(sizeof(unsigned long));
А>    if(begin==NULL) {
А>        printf("error : begin==NULL (not enough memory)"); // такое поведение malloc оговорено в документации
А>        return -1;
А>    }
А>    for(unsigned long i=1;i<100000;++i) {
А>        begin[i-1]=i-1;
А>        unsigned long* begin_prev=begin;
А>        begin=(unsigned long*)realloc(begin,sizeof(unsigned long)*(i+1));
А>        if(begin_prev!=begin) {
А>            printf("memory moved. OK\n"); // такое поведение realloc оговорено в документации
А>        }
А>        if(begin==NULL) {
А>            printf("error : begin==NULL (not enough memory)"); // такое поведение realloc оговорено в документации
А>            return -1;
А>        }
А>        for(unsigned long j=0;j<i;j++) {
А>            if(begin[j]!=j) {
А>                printf("realloc doesn't work properly : begin[j]!=j"); // такого быть не может, иначе это ошибка в реализации realloc
А>                return -1;
А>            }
А>        }
А>    }
А>    printf("test passed successfully");

А>    return 0;
А>}
А>



Хорошо. Вечером проверю. Спасибо.
Re[6]: realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 06.10.04 04:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>твой код не падает.

А>явных ошибок нет, точнее сказать не могу с назначением функции не разбирался
А>ниже код который тестирует реализацию realloc.
А>ошибок в реализации realloc он не выявил — запусти у себя — скажешь результат, или сам чего поймешь по коду.
А>предлагаю тебе переписать твою функцию, скорее всего realloc работает правильно, а ошибки у тебя в программе
А>и добавь пожалуй в свой код после realloc проверку if(begin==NULL) { printf("error : not enough memory"); }

А>
А>int main(int argc, char* argv[])
А>{
А>    unsigned long* begin=(unsigned long*)malloc(sizeof(unsigned long));
А>    if(begin==NULL) {
А>        printf("error : begin==NULL (not enough memory)"); // такое поведение malloc оговорено в документации
А>        return -1;
А>    }
А>    for(unsigned long i=1;i<100000;++i) {
А>        begin[i-1]=i-1;
А>        unsigned long* begin_prev=begin;
А>        begin=(unsigned long*)realloc(begin,sizeof(unsigned long)*(i+1));
А>        if(begin_prev!=begin) {
А>            printf("memory moved. OK\n"); // такое поведение realloc оговорено в документации
А>        }
А>        if(begin==NULL) {
А>            printf("error : begin==NULL (not enough memory)"); // такое поведение realloc оговорено в документации
А>            return -1;
А>        }
А>        for(unsigned long j=0;j<i;j++) {
А>            if(begin[j]!=j) {
А>                printf("realloc doesn't work properly : begin[j]!=j"); // такого быть не может, иначе это ошибка в реализации realloc
А>                return -1;
А>            }
А>        }
А>    }
А>    printf("test passed successfully");

А>    return 0;
А>}
А>


Проверил я ваш код. Он не работает. На какой-то итерации он зависает на строке "memory moved. OK"
Re[6]: realloc неправильно выделяет память...
От: Звероящер Россия  
Дата: 06.10.04 04:41
Оценка:
Здравствуйте, yeti, Вы писали:

Y>Здравствуйте, Звероящер, Вы писали:


З>>Вот та функция

З>>[...]

Y>я так понял что это перевод десятичного числа в двоично-десятичное только байты в другом порядке?

Y>в любом случае переписал нормально; у меня (VC6 и VC8) работает, как впрочем и ваш вариант.
Y>вы уверены что проблема именно в этой функции, т.е. воспроизводится ли ошибка в пустом проекте, содержащем только её вызов?
Y>вообще если проблема не исчезнет — покажите как вы её вызываете.

Y>мой код:

Y>
Y>unsigned long *inputvalue(int *dwords)
Y>{
Y>    unsigned long *data = NULL;
Y>    int c, digits = 0;
Y>    *dwords = 0;

Y>    while( (c=getch()) != 13 )
Y>    {
Y>        if( ! isdigit(c) ) continue;
Y>        printf("%c", c);
Y>        c -= '0'; // '7' --> 7

Y>        if(digits == 0)
Y>        {
Y>            ++*dwords;
Y>            data = (unsigned long *)realloc(data, *dwords * sizeof(unsigned long));
Y>            if( data == NULL )
Y>            {
Y>                fputs("error: out of memory\n", stderr);
Y>                exit(13);
Y>            }
Y>            digits = sizeof(unsigned long) * (8 / 4); // 8 bits per byte, 4 bits per digit
Y>            data[*dwords - 1] = 0;
Y>        }

Y>        data[*dwords - 1] <<= 4;
Y>        data[*dwords - 1]  |= c;
Y>        --digits;
Y>    }

Y>    puts("");
Y>    return data;
Y>}
Y>


Проверил. Работает железно. В чем прикол не пойму. Единственное, что приходит в голову, у меня всегда была область выделенной, но НЕИНИЦИАЛИЗИРОВАННОЙ памяти. То есть с помощью realloc'а я выделял не столько памяти, сколько нужно, а еще +1. И при вызове realloc'а в следующий раз в конце эта память оставалась незаполненной данными. Очень интересно все это. Получается, что выделенную память надо забить до упора, а потом увеличивать...
Re: realloc неправильно выделяет память...
От: Dr.Gigabit  
Дата: 07.10.04 13:29
Оценка:
Здравствуйте, Звероящер, Вы писали:

З>Пишу под VC++6.

З>Пользуюсь стандартными функциями malloc и realloc.

З>короче по мере надобности увеличиваем память на unsigned long каждый раз. Но это не всегда работает верно. Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.

З>Кто с этим сталкивался и как боролся?

Использовать средства С++ а не C.
На сколько я помню,поведение realloc достаточно странное и заметно отличается от других компиляторов...
... << RSDN@Home 1.1.4 @@subversion >>
Re: realloc неправильно выделяет память...
От: FR  
Дата: 08.10.04 13:35
Оценка:
Здравствуйте, Звероящер, Вы писали:


З>короче по мере надобности увеличиваем память на unsigned long каждый раз. Но это не всегда работает верно. Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.

З>Кто с этим сталкивался и как боролся?

Вообще то realloc не гарантирует что во вновь выделенная память будет очищена.
... << RSDN@Home 1.1.3 stable >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.