Search code examples
cmallocfreedynamic-memory-allocationcalloc

Unable to properly free malloc of another malloc


Here's the snippet with issues.

int main()
{
    char** RESERV = (char**)malloc(sizeof(char*)*4);
    printf("%i, %i, %i, %i, %i", **RESERV, *RESERV, RESERV, &**RESERV, sizeof(char*));
    int i;
    for(i = 0; i < 4; i++)
    {
        RESERV[i] = (char*)calloc(sizeof(char),16);
        RESERV[i][15] = '\0';
    }
    for(i = 0; i < 4; i++)
        RESERV[i]="Iambananananananananananana";
    for(i = 0; i < 4; i++)
        printf("\r\n>%i<", RESERV[i]);
    for(i = 0; i < 4; i++)
    {
        printf("\r\n<%i>", (RESERV[i]));
        free(RESERV[i]);
    }
    free(RESERV);
}

This code free() is working fine in 32 bit , but somehow crashes horribly in 64 bit mode.

In my main program I've omitted freeing the members of the char** causing unexptected behavior every now and then, which I obviously do not want.

I've tried playing around with addresses and pointers, even tried

free(RESERV+(i*sizeof(char*))

Which failed too. Can someone clarify what I'm doing wrong?


Solution

  • In your code

     RESERV[i]="Iambananananananananananana";
    

    creates the problem. It overwrites the memory allocated by malloc(). Thus,

    1. You face memory leak, because the malloc()ed pointer is lost.
    2. You cannot call free() with the changed pointer. It invokes undefined behaviour.

    Solution:

    In C, you don't assign strings, instead, you can use strcpy() to get your work done.

    Notes:

    1. even in case of strcpy() you cannot use "Iambananananananananananana". In this case, it will create memory overrun as destination does not have enough memory to hold it completely.

    2. Use proper format specifiers. in your printf() statements, most of the arguments to %i are not of type int. For pointer type arguments, you should be using %p, atleast. Otherwise, it will be UB.