Thread: Question about Free() and Ptr-Ptr-Int

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    8

    Question about Free() and Ptr-Ptr-Int

    So I have a function where I have allocated space dynamically for an array of pointers to ints.

    Then I dynamically create arrays of ints for each of those pointers.

    Then I've returned the base address of the array of pointers to main and do stuff with it...

    I now have to release the space that was allocated (for an assignment). The professor has given me this function prototype:

    void FreeMatrix(int **matrix);

    I'm supposed to free the space with a pointer to a pointer to an int. Here is my question: if I do a free(matrix), will that free all the allocated space, or do I have to free each element?

    If I have to go in and free each element, how would I know how many elements I need to free?

    I was thinking if I would be able to do a sizeof(*matrix) to find out??

    I ask because I am not sure(obviously) and would like to know if my function is releasing all the memory or if my OS is.


    Please and thanks!

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You would have to free every pointer that came from a malloc. If you don't somehow know how many rows in your table were allocated, you are SOL.

  3. #3
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Well this function doesn't know how many rows there are so there isn't an option for me?

    I guess I will ask the professor then...

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you can try and sneak a global variable in somewhere (shudder), then you can use that. Otherwise, that's it.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Kehyn View Post
    If I have to go in and free each element, how would I know how many elements I need to free?
    This is a harder problem to create than you maybe think, but anyway.

    One failsafe is: unallocated pointers are assigned NULL when declared:
    Code:
    void *ptr = NULL;
    if it's in a struct, initialize the members to NULL or you zero out the struct (which NULLs the pointers).

    Next, de-allocated pointers are assigned NULL:
    Code:
    free(ptr);
    ptr = NULL;
    Finally, when cleaning-up: never free a NULL pointer, always free a non-NULL pointer:
    Code:
    if (ptr) {   // NULL == FALSE, or 0. Everything else is TRUE.
       free(ptr);
       ptr = NULL;
    }
    This is not the most optimal method but it's cheap enough and works well.
    Last edited by MK27; 04-14-2010 at 08:05 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Hey I just realized the obvious way to make this work, and MK has most of it:

    Quote Originally Posted by MK27 View Post
    This is a harder problem to create than you maybe think, but anyway.

    One failsafe is: unallocated pointers are assigned NULL when declared:
    Code:
    void *ptr = NULL;
    if it's in a struct, initialize the members to NULL or you zero out the struct (which NULLs the pointers).

    Next, de-allocated pointers are assigned NULL:
    Code:
    free(ptr);
    ptr = NULL;
    Finally, when cleaning-up: never free a NULL pointer, always free a non-NULL pointer:
    Code:
    if (ptr) {   // NULL == FALSE, or 0. Everything else is TRUE.
       free(ptr);
       ptr = NULL;
    }
    This is not the most optimal method but it's cheap enough and works well.
    You missed out the most important part: you will always need to have one "extra" pointer at the end of your table that is NULL, which tells you when to stop. (Otherwise you'll just go off into somebody else's memory and free it instead.)

    It's not late enough for me to be forgetting things like this; where's my Mountain Dew?

  7. #7
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Quote Originally Posted by MK27 View Post
    This is a harder problem to create than you maybe think, but anyway.

    One failsafe is: unallocated pointers are assigned NULL when declared:
    Code:
    void *ptr = NULL;
    if it's in a struct, initialize the members to NULL or you zero out the struct (which NULLs the pointers).

    Next, de-allocated pointers are assigned NULL:
    Code:
    free(ptr);
    ptr = NULL;
    Finally, when cleaning-up: never free a NULL pointer, always free a non-NULL pointer:
    Code:
    if (ptr) {   // NULL == FALSE, or 0. Everything else is TRUE.
       free(ptr);
       ptr = NULL;
    }
    This is not the most optimal method but it's cheap enough and works well.
    This is fine and dandy, but no use to me. :0

    Quote Originally Posted by tabstop View Post
    If you can try and sneak a global variable in somewhere (shudder), then you can use that. Otherwise, that's it.
    The problem is that during my program, I ask the user for the amount of rows and colums and allocate the "2D" array with that information...so globals are out.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Kehyn View Post
    The problem is that during my program, I ask the user for the amount of rows and colums and allocate the "2D" array with that information...so globals are out.
    There's nothing inherent about asking for input that says the variables can't be global. (Again, not necessarily good design, but we're in a bit of a box here.)

  9. #9
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    So I should be able to do something like:

    Code:
    if (NULL != matrix[i])
         {
          free(matrix[i]);
          }
    I don't think I understand. If I have a block of memory out there somewhere and just beyond my memory is another pointer that isn't NULL this shouldn't work...

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Kehyn View Post
    So I should be able to do something like:

    Code:
    while (NULL != matrix[i])
         {
          free(matrix[i++]);
          }
    I don't think I understand. If I have a block of memory out there somewhere and just beyond my memory is another pointer that isn't NULL this shouldn't work...
    That's why if the person asks for n rows, you have malloc give you n+1 pointers and make the last one NULL. Yes this wastes a massive 4 bytes of storage. And notice the fix to the code.

  11. #11
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Quote Originally Posted by tabstop View Post
    That's why if the person asks for n rows, you have malloc give you n+1 pointers and make the last one NULL. Yes this wastes a massive 4 bytes of storage. And notice the fix to the code.
    K I think I'll try that....I was just providing an example that would probably be in a for loop or something...

  12. #12
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Hellz yea, got it to work. Thanks tabstop and MK27 for your help.
    Last edited by Kehyn; 04-14-2010 at 09:05 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 01-23-2010, 03:37 PM
  2. creating a sorted list
    By S15_88 in forum C Programming
    Replies: 3
    Last Post: 03-20-2008, 01:14 AM
  3. Question about free()
    By Mr_Miguel in forum C Programming
    Replies: 4
    Last Post: 12-07-2007, 01:25 PM
  4. Replies: 10
    Last Post: 05-18-2006, 11:23 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM