1. We have moved from vBulletin to XenForo and you are viewing the site in the middle of the move. Though the functional aspect of everything is working fine, we are still working on other changes including the new design on Xenforo.
    Dismiss Notice

Clarification regarding malloc and free in C

Discussion in 'C' started by Seth442, Feb 8, 2010.

  1. Seth442

    Seth442 New Member

    Joined:
    Feb 8, 2010
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Suppose I were to write the following code:

    int *p = malloc(sizeof(int) * 10);
    int *q;
    q = p + 1;
    free(q);

    Will calling free with argument q free up the entire block of "size" 10? Or will it only free up the 2nd through 10th spots?

    Is there any circumstance in which memory that has been allocated using malloc is freed without explicitly calling free?

    Thank you!
     
  2. Gene Poole

    Gene Poole New Member

    Joined:
    Nov 10, 2009
    Messages:
    93
    Likes Received:
    5
    Trophy Points:
    0
    Since you are calling free on a pointer that was NOT allocated by malloc, the behavior is undefined.
     
  3. Seth442

    Seth442 New Member

    Joined:
    Feb 8, 2010
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Oh ok, I thought the important thing was that the argument of free pointed to memory that had been malloc'ed. I did not realize that the argument itself had to have been initialized with malloc.

    What about the following code:

    int *makePointer (VOID)
    {
    int *p = malloc(sizeof(int) * 10);
    return p;
    }

    int main ()
    {
    int *ptr;
    ptr = makePointer();
    }

    Can I call free with the argument ptr in main? If I cannot, then how do I free up the memory?

    And what if I wrote the following:

    int *p = malloc(sizeof(int) * 10);
    int *q = malloc(sizeof(int) * 9);
    p = q;
    free(p);

    Is the malloced memory of size 10 freed? Or of size 9? Or is the behavior undefined?

    What if I had a pointer p that had been initialized with malloc and then I assigned it to point to a different address, but did not save the original address. Does that mean I can no longer free the memory?

    What if I had a pointer p that had been initialized with malloc , I stored the address in a variable x, then I assigned p to point somewhere else, then I reassigned p to point to the address stored in x. Then can I call free with argument p to free up that memory?

    Does anyone know where I can read an in depth explanation of some of these details? It is really bugging me.
     
  4. Gene Poole

    Gene Poole New Member

    Joined:
    Nov 10, 2009
    Messages:
    93
    Likes Received:
    5
    Trophy Points:
    0
    Typically the memory manager keeps track of malloc'ed memory by storing the pointer in a table and when free or realloc, etc. are called, it looks up the pointer in its table so the the value of the actual pointer is the lookup key. So, with respect to the first part of your post, yes, you can free the pointer returned by the function since its value is the same.

    In the second case, you are reassigning your pointer to a different location and therefore the memory allocated by p is left dangling with no way to free it.
     
  5. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    > Can I call free with the argument ptr in main?

    Yes.

    > And what if I wrote the following...?

    You would have a memory leak because you would have no way of freeing the memory at p.

    > Does that mean I can no longer free the memory?

    Yes. The memory would remain allocated and this is a memory leak.

    > What if ...(complicated stuff I couldn't be bothered to decipher)

    If you allocate memory, you MUST MUST MUST MUST keep the pointer given you by malloc. It doesn't matter where you keep it, you can keep it in p, copy it to x, write it to disk, punch it to paper tape, burn it onto the moon with a laser, anything you like, as long as when you're done with the memory you can retrieve the pointer and pass it to free. Then the memory will be correctly deallocated. It will NOT be correctly deallocated if you do not follow this very simple rule.

    ptr=malloc(n) -> Keep the value in ptr.

    free(ptr) -> ptr here must be the value returned by malloc.
     
  6. rekha_sri

    rekha_sri New Member

    Joined:
    Feb 20, 2010
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    0
    When you want to call the free function,you should use the argument as
    which is returned by the previous call of the malloc.Otherwise it would display the error like invalid pointer in free(). If you already called the free(), again tried to call the free() with same pointer variable behavior is undefined.
     
  7. sganesh

    sganesh New Member

    Joined:
    Feb 19, 2010
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    int *p=(int *)malloc(12);
    free(p);

    Your question is whether calling free function with argument p will clear the remaining elements.

    It won't Because free will clear the first location which is pointed by p. If you want to clear all locations that is allocated by malloc. you need to use loop you need to have the temporary pointer then freeing it then move to the next pointer.
     
  8. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,276
    Likes Received:
    364
    Trophy Points:
    83
    You need to work on your knowledge of Free and Malloc. This is completely not true.
     
  9. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    Absolutely. free(p) will free the 12 bytes that were allocated by malloc(12). sganesh, wherever you got that idea from, it's complete nonsense.

    Now if you do
    Code:
    int **p=malloc(12*sizeof(int*));
    for (int i=0; i<12; i++)
      p[i]=malloc(12*sizeof(int));
    
    (which creates a 2D array of 144 ints), THEN you will need a loop to free each of p before you free p itself. Observe then that the malloc's exactly match the free's (there will be 13 of each). Every malloc must be matched by *exactly* one free for the application not to exhibit undefined behaviour.
     
  10. sganesh

    sganesh New Member

    Joined:
    Feb 19, 2010
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    can you tell me which is not true.

    I am coming to say pointer is like an array. If you free one location it is not mean that other locations also cleared.
     
  11. sganesh

    sganesh New Member

    Joined:
    Feb 19, 2010
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0


    I think you completely misunderstood me. free(p) will free the 12 bytes that were allocated by malloc(12) I also said that it is false. It will free only one pointer(location) that is pointed by p.
     
  12. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,276
    Likes Received:
    364
    Trophy Points:
    83
    You told that for freeing memory you will need a loop but that is completely false. You do not need a loop
     
  13. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    You asked what parts of what you said were false. Just about every point you made was false.

    > Because free will clear the first location which is pointed by p.

    False. If p=malloc(x) then free(p) will free *ALL* x bytes. Not just the first.

    > If you want to clear all locations that is allocated by malloc. you need to use loop you need to have the temporary pointer then freeing it then move to the next pointer.

    False. If p=malloc(x) then free(p) will free *ALL* x bytes. My post suggested you may have confused this with allocating an array of pointers then individually mallocing each of those pointers. In that case, yes you will need to free each individual pointer before freeing the array of pointers. But your argument is that if p=malloc(x) then to free this you need free(p), free(p+1), free(p+2), ..., free(p+x-1) in order to free all x bytes. THIS IS FALSE. If you think it's true, what is your source? Where did you get this idea from?

    > free(p) will free the 12 bytes that were allocated by malloc(12) I also said that it is false. It will free only one pointer(location) that is pointed by p.

    Wrong again. If p=malloc(12) then free(p) will free *ALL* 12 bytes. You *DO NOT* need 12 calls to free().

    You don't have to take it from me (a site Mentor with over 1000 posts) and shabbir (the site Admin) who both disagree with you. You can also take it from:

    Wikipedia http://en.wikipedia.org/wiki/Malloc which states "free(void *pointer) ... releases the block of memory pointed to by pointer"

    the Gnu documentation http://www.gnu.org/s/libc/manual/html_node/Freeing-after-Malloc.html

    cplusplus.com: http://www.cplusplus.com/reference/clibrary/cstdlib/free/

    It's perfectly OK that you've misunderstood something, hence my asking "where did you get this wrong idea from" so that we could perhaps help you see how you've misunderstood.
     

Share This Page