Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Вызовет ли realloc утечку памяти?

#c #memory_leaks #realloc


Доброго времени суток! Есть код:

// mry_char*  - это wchar_t*
// mry_charsz - это sizeof(wchar_t)

void mry_strcat(mry_char* _dest, const mry_char const* _src) {
    const u32 dl = mry_strlen(_dest);
    const u32 sl = mry_strlen(_src);

    _dest = realloc(_dest, (dl + sl + 1) * mry_charsz);
    memmove(_dest + dl, _src, sl * mry_charsz);
    _dest[dl + sl] = '\0';
}


Cppcheck пишет:

Id: memleak
Кратко: Memory leak: _dest
Сообщение: Memory leak: _dest

First included by: mary.c

Строка 69: _dest[dl + sl] = '\0';


Я так понимаю, что утечка будет, если realloc переместит блок при возрастании размера,
так ли это?

UPD

Исправил выход за границы массива.
    


Ответы

Ответ 1



В своем коде вы должны рассчитывать на то, что realloc будет всегда перемещать блок, независимо от того, увеличивается ли его размер, уменьшается ли или вообще не меняется. Эти решения принимаются на основе неподконтрольных вам обстоятельств. То, что он может иногда и не переместиться - не более чем редкая и непредсказуемая удача. Утечка у вас образуется из-за того, что новое значение указателя _dest в наружный код никак не возвращается. Память, выделенная вашим realloc в общем случае становится утечкой всегда. Либо возвращайте новый _dest из функции через возвращаемое значение, либо работайте с ним "по ссылке", т.е. делайте его mry_char** параметром. (Да, если в результате работы realloc значение указателя _dest не изменилось, то формально возвращать его "не нужно", но ожидать этого в реальном коде - это полная белиберда. В общем случае значение указателя будет меняться.) Дополнительно, в связи именно c realloc утечка также может возникнуть, если realloc не сможет выделить память вообще. Тогда он вернет null-указатель, но старую память не освободит, т.е. внутри функции доступ к памяти, изначально указываемой _dest, вы потеряете. (Будет ли это полноценной утечкой зависит от того, сохранили ли вы еще какой-то путь доступа к этой памяти. Из вашего кода этого не видно.) Также, почему памяти выделяется только под dl + sl элементов, если потом делается _dest[dl + sl] = '\0'? Явный вылет за пределы выделенной памяти.

Ответ 2



Утечки как таковой из-за realloc не появляется - если вы не забудете потом удалить выделенную память. Другое дело, что вы 1. не проверяете результат realloc (и не сохраняете его) 2. выделяете недостаточно памяти (есть выход за границу) 3. Насколько я помню, для wchar_t надо записывать не '\0', а L'\0'

Комментариев нет:

Отправить комментарий