Страницы

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

пятница, 2 ноября 2018 г.

Вызовет ли 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
Исправил выход за границы массива.


Ответ

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

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

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