realloc () утечка памяти - PullRequest
       3

realloc () утечка памяти

0 голосов
/ 28 декабря 2010

У меня есть функция, которая добавляет символ в строку:

void AddChToString(char **str,char ch){
    int len=(*str)?strlen(*str):0;
    (*str)=realloc(*str, len+2);
    (*str)[len]=ch;
    (*str)[len+1]='\0';
}

Инструменты (на Mac) и Valgrind указывают, что строка: (* str) = realloc (* str, len + 2) утечка памяти. Это проблема реализации с realloc? Или я неправильно его использую?

Вот вывод из Valgrind:

==39230== 6 bytes in 1 blocks are definitely lost in loss record 1 of 7
==39230==    at 0x100018B2D: realloc (vg_replace_malloc.c:525)
==39230==    by 0x100002259: AddChToString (in ./OpenOtter)
==39230==    by 0x10000477B: QueryMapFromString (in ./OpenOtter)
==39230==    by 0x100684CD2: ???
==39230==    by 0x100001FB0: RequestHandler (in ./OpenOtter)
==39230==    by 0x100065535: _pthread_start (in /usr/lib/libSystem.B.dylib)
==39230==    by 0x1000653E8: thread_start (in /usr/lib/libSystem.B.dylib)
==39230== 
==39230== 9 bytes in 1 blocks are definitely lost in loss record 2 of 7
==39230==    at 0x100018B2D: realloc (vg_replace_malloc.c:525)
==39230==    by 0x100002259: AddChToString (in ./OpenOtter)
==39230==    by 0x10000298E: ParseHTTPRequest (in ./OpenOtter)
==39230==    by 0x100004151: OpenRoutesFile (in ./OpenOtter)
==39230==    by 0x10000142B: main (in ./OpenOtter)
==39230== 
==39230== 45 bytes in 5 blocks are definitely lost in loss record 3 of 7
==39230==    at 0x100018B2D: realloc (vg_replace_malloc.c:525)
==39230==    by 0x100002259: AddChToString (in ./OpenOtter)
==39230==    by 0x10000298E: ParseHTTPRequest (in ./OpenOtter)
==39230==    by 0x100001EB4: RequestHandler (in ./OpenOtter)
==39230==    by 0x100065535: _pthread_start (in /usr/lib/libSystem.B.dylib)
==39230==    by 0x1000653E8: thread_start (in /usr/lib/libSystem.B.dylib)
==39230== 
==39230== LEAK SUMMARY:
==39230==    definitely lost: 60 bytes in 7 blocks
==39230==    indirectly lost: 0 bytes in 0 blocks
==39230==      possibly lost: 0 bytes in 0 blocks
==39230==    still reachable: 1,440 bytes in 4 blocks
==39230==         suppressed: 0 bytes in 0 blocks

Спасибо.

Ответы [ 4 ]

8 голосов
/ 28 декабря 2010

Показывает ли ваша аппаратура фактическую утечку или потенциальную утечку?

Использование realloc(), как вы, приведет к утечке памяти , если realloc() не удастся. В этом случае он вернет NULL, но не освободит исходный блок. Таким образом, вы потеряете указатель на блок и не сможете его освободить (если указатель не хранится в другом месте).

Но это должно быть редким явлением (т. Е. Когда вы исчерпали память).

Если это то, на что жалуются ваши инструменты, вы сможете исправить предупреждение об утечке примерно так:

void AddChToString(char **str,char ch){
    int len=(*str)?strlen(*str):0;
    char* tmp = realloc(*str, len+2);

    if (!tmp) {
        // whatever error handling is appropriate
    }

    (*str)=tmp;
    (*str)[len]=ch;
    (*str)[len+1]='\0';
}
3 голосов
/ 28 декабря 2010

Вызов самому realloc не приводит к утечке памяти. Вы должны убедиться, что память для перераспределенной строки освобождается бесплатно после того, как она больше не нужна.

2 голосов
/ 28 декабря 2010

Я не знаю о проблемах с реализацией realloc, но в этом коде наверняка есть возможность утечки памяти: из справочной страницы realloc:

Если realloc() не удается, исходный блок остается нетронутым; оно не освобождается и не перемещается.

и, поскольку realloc возвращает NULL в случае сбоя, в случае сбоя вы теряете единственный указатель на уже выделенный блок памяти, поэтому у вас возникает утечка памяти.

Чтобы избежать проблемы, вы должны сделать:

char * temp=realloc(*str, len+2);
if(temp==NULL)
{
    /* handle the error in some way */
}
else
    *str=temp;
0 голосов
/ 28 декабря 2010

попробуйте перераспределить, используя отдельную переменную, затем вызовите strcpy, чтобы получить переменную str в это пространство, например:

void AddChToString(char **str,char ch){
char *blah;
int len=(*str)?strlen(*str):0;
blah=realloc(NULL, len+2);
strcpy(blah, str); 
(*str)[len]=ch;   
(*str)[len+1]='\0'; } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...