Пишу под 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'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.
Кто с этим сталкивался и как боролся?
Здравствуйте, Звероящер, Вы писали:
З>Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.
Откуда такая уверенность про используемую память?
Re: realloc неправильно выделяет память...
От:
Аноним
Дата:
04.10.04 07:41
Оценка:
Здравствуйте, Звероящер, Вы писали:
Проверяешь ли ты возвращаемое значение при вызовах malloc и realloc?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Звероящер, Вы писали:
А>Проверяешь ли ты возвращаемое значение при вызовах malloc и realloc?
Сравниваешь ли begin и NULL?
Здравствуйте, bkat, Вы писали:
B>Здравствуйте, Звероящер, Вы писали:
З>>Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении.
B>Откуда такая уверенность про используемую память?
Это видно из дебаггера... Неинциализированная память выглядит отлично от упорядоченой и потом, когда я пишу в эту память, все сбоит.
Re[3]: realloc неправильно выделяет память...
От:
Аноним
Дата:
04.10.04 12:03
Оценка:
Здравствуйте, Звероящер, Вы писали:
Приведи пример кода, который демонстрирует неправильную работу realloc (например падает при запуске).
Здравствуйте, Звероящер, Вы писали:
З>короче по мере надобности увеличиваем память на unsigned long каждый раз. Но это не всегда работает верно. Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении. З>Кто с этим сталкивался и как боролся?
А надо ли с этим бороться? realloc имеет право выделить память на том же месте.
Если же он выделил память в другом месте, то ты не имеешь права обращаться к предыдущей, кстати.
>realloc неправильно выделяет память...
он не выделяет, он перевыделяет. И копирует (если выделил на новом месте).
Может, лучше воспользоваться std::vector? все-таки VC++6.
Правильно работающая программа — просто частный случай Undefined Behavior
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Звероящер, Вы писали:
А>Приведи пример кода, который демонстрирует неправильную работу realloc (например падает при запуске).
Вот та функция
unsigned long *inputvalue(int *len)
{ char num[]="0123456789";
char c;
int i,j,k;
unsigned long *begin, cnt;
Здравствуйте, Звероящер, Вы писали:
З>Вот та функция З>[...]
я так понял что это перевод десятичного числа в двоично-десятичное только байты в другом порядке?
в любом случае переписал нормально; у меня (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' --> 7if(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"); // такого быть не может, иначе это ошибка в реализации reallocreturn -1;
}
}
}
printf("test passed successfully");
return 0;
}
Здравствуйте, yeti, Вы писали:
Y>Здравствуйте, Звероящер, Вы писали:
З>>Вот та функция З>>[...]
Y>я так понял что это перевод десятичного числа в двоично-десятичное только байты в другом порядке? Y>в любом случае переписал нормально; у меня (VC6 и VC8) работает, как впрочем и ваш вариант. Y>вы уверены что проблема именно в этой функции, т.е. воспроизводится ли ошибка в пустом проекте, содержащем только её вызов? Y>вообще если проблема не исчезнет — покажите как вы её вызываете.
Y>мой код: Y>
Да эта функция пакует десятичные цифры в тетрады. И если ввести этот realloc вызвается раз 10 (для установки длины unsigned long *10), то ошибка и вылазит...
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Звероящер, Вы писали:
З>>Здравствуйте, Аноним, Вы писали:
А>>>Здравствуйте, Звероящер, Вы писали:
А>>>Приведи пример кода, который демонстрирует неправильную работу 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;
А>}
А>
Здравствуйте, Аноним, Вы писали:
А>твой код не падает. А>явных ошибок нет, точнее сказать не могу с назначением функции не разбирался А>ниже код который тестирует реализацию 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"
Здравствуйте, yeti, Вы писали:
Y>Здравствуйте, Звероящер, Вы писали:
З>>Вот та функция З>>[...]
Y>я так понял что это перевод десятичного числа в двоично-десятичное только байты в другом порядке? Y>в любом случае переписал нормально; у меня (VC6 и VC8) работает, как впрочем и ваш вариант. Y>вы уверены что проблема именно в этой функции, т.е. воспроизводится ли ошибка в пустом проекте, содержащем только её вызов? Y>вообще если проблема не исчезнет — покажите как вы её вызываете.
Y>мой код: Y>
Проверил. Работает железно. В чем прикол не пойму. Единственное, что приходит в голову, у меня всегда была область выделенной, но НЕИНИЦИАЛИЗИРОВАННОЙ памяти. То есть с помощью realloc'а я выделял не столько памяти, сколько нужно, а еще +1. И при вызове realloc'а в следующий раз в конце эта память оставалась незаполненной данными. Очень интересно все это. Получается, что выделенную память надо забить до упора, а потом увеличивать...
Здравствуйте, Звероящер, Вы писали:
З>Пишу под VC++6. З>Пользуюсь стандартными функциями malloc и realloc.
З>короче по мере надобности увеличиваем память на unsigned long каждый раз. Но это не всегда работает верно. Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении. З>Кто с этим сталкивался и как боролся?
Использовать средства С++ а не C.
На сколько я помню,поведение realloc достаточно странное и заметно отличается от других компиляторов...
З>короче по мере надобности увеличиваем память на unsigned long каждый раз. Но это не всегда работает верно. Было замечено, что при определённом количестве вызове realloc'а, память выделяется не пустая, а уже используемая, что приводит к сбою программы. Это хорошо видно в пошаговом выполнении. З>Кто с этим сталкивался и как боролся?
Вообще то realloc не гарантирует что во вновь выделенная память будет очищена.