Потенциальная утечка Mem: Mallo c для блока и бесплатная для частей блока? - PullRequest
0 голосов
/ 17 марта 2020

Я работаю с устаревшим кодом C ++, который резервирует блок памяти с помощью mallo c и делит его на части, которые освобождаются отдельно. Примерно так:

const int N_floats_per_buffer = 100;
const int N_buffers = 2;
//reserve buffers en bloque
float * buffer = (float*) malloc(N_float_per_buffer * N_buffers * sizeof(float));
//then this block memory is divided into sub-blocks
float * sub_buffer[N_buffers];
for(int j = 0; j < N_buffers; ++j)
{
    sub_buffer[j] = buffer + j*N_floats_per_buffer;
}
//do something with the buffers...
//...
//finally: memory is freed for the individual buffers
for(int j = 0; j < N_buffers; ++j)
{
    if(sub_buffer[i]!=NULL) free(sub_buffer[j]);
}

Это на самом деле еще более запутанно в реальном коде, но я думаю, что я понял его суть.

Мой вопрос : это утечка памяти?

1 Ответ

2 голосов
/ 17 марта 2020

Это не утечка памяти. Хуже, неопределенное поведение.

Вы можете вызывать free только для указателя, возвращенного из malloc (или calloc, et c.). Вам не разрешено вызывать free для указателя, указывающего куда-либо еще в возвращенном блоке хранения. Это приводит к неопределенному поведению.


Также на стороне более pedanti c, malloc не создает никаких объектов, а arithmeti pointer c требует, чтобы указатель указывал на элемент массива объект для него иметь четко определенное поведение в C ++. Следовательно, технически у вас уже есть неопределенное поведение, когда вы делаете

buffer + j*N_floats_per_buffer

, хотя, вероятно, все компиляторы ведут себя так, как ожидалось (даже если стандарт не дает никаких гарантий). Это было решено только недавно для C ++ 20, где требуемый массив будет создан неявно.

Почти всегда следует использовать new / delete, а не malloc / free в C ++ .

...