Search code examples
c++memory-leaksmallocfree

Potential Mem leak: Malloc for block and free for parts of the block?


I am working with legacy C++ code that reserves a block of memory using malloc and divides it up into parts that are freed separately. Something like this:

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]);
}

It is actually even more confusing in the real code but I think I have captured the essence of it.

My question is: is that a memory leak?


Solution

  • It is not a memory leak. It is worse, undefined behavior.

    You can only call free on a pointer returned from malloc (or calloc, etc.). You are not allowed to call free on a pointer pointing somewhere else in the returned storage block. Doing that causes undefined behavior.


    Also on a more pedantic side, malloc does not create any objects and pointer arithmetic requires the pointer to point to an element of an array object for it to have well-defined behavior in C++. Therefore you technically already have undefined behavior when you do

    buffer + j*N_floats_per_buffer
    

    although probably all compilers behave as expected (even though the standard made no guarantees). This was only resolved recently for C++20, where the required array will be created implicitly.

    One should almost always only use new/delete, not malloc/free in C++.