Search code examples
cpointersmemory-managementmalloccalloc

Allocating a pointer with calloc, and then dynamically allocate each cell with malloc = memory leakage?


In a recent exam question I got this code with following options:

char **mptr, *pt1;
int i;
mptr = calloc(10, sizeof(char*));
for (i=0; i<10; i++)
{
    mptr[i] = ( char *)malloc(10);
}   

Which of the following de-allocation strategies creates a memory leakage?

A. free(mptr);

B. for(i = 0; i < 10; i++): { free(mptr[i]); }

C. All of them

The answer is C. But it seems to me that applying free(mptr); would suffice covering the memory leak, and B as well, although I'm less sure of that, can someone explain me why all of them would cause a memory leak? I'm guessing the C options expects that each operation ( A or B ) are applied separatly.

P.S. I don't see the point of this code, if you already have allocated memory with calloc (and initialized it) why would you go as far as to allocate each cell with a cycle? Am I wrong to believe that?


Solution

  • Which of the following de-allocation strategies creates a memory leakage?

    In my pedantic opinion the correct answer would have to be option A, it creates a memory leak because it deallocates mptr, making mptr[i] pointers inaccessible. They cannot be deallocated afterwards, assuming that the memory is completely inaccessible by other means.

    Option B does not lead to memory leak per se, mptr is still accessible after you free mptr[i] pointers. You can reuse it or deallocate it later. Memory leak would only occur if and when you loose access to the memory pointed by mptr.

    I believe the question is somewhat ill-formed, if the question was "Which option would you use to correctly deallocate all the memory?", then yes, option C would be correct.

    I do agree that the correct strategy to deallocate all the memory is B + A, albeit A first will cause immediate memory leak whereas B first will allow for later deallocation of mptr, as long as the access to the memory pointed by it is not lost.

    I don't see the point of this code, if you already have allocated memory with calloc (and initialized it) why would you go as far as to allocate each cell with a cycle? Am I wrong to believe that?

    The allocation is correct.

    //pointer to pointer to char, has no access to any memory
    char **mptr;
    
    //allocates memory for 10 pointers to char
    mptr = calloc(10, sizeof(char*));
    
    //allocates memory for each of the 10 mptr[i] pointers to point to
    for (i = 0; i < 10; i++)
    {
        mptr[i] = malloc(10); //no cast needed, #include <stdlib.h>
    }
    

    Check this thread for more info.