free'ing malloc'd structure with malloc'd members

Discussion in 'C Programming' started by John, Jul 30, 2004.

  1. John

    John Guest

    In the course of an assignment, I learned the hard way that I shouldn't try
    to free a malloc'd member of a malloc'd structure after having freed that
    structure (i.e., free( structure ); free( structure->bufferspace ) ).

    My question is, if I free just the structure, will the (e.g.) bufferspace be
    freed implicitly, or do I have to (as I currently am) free the members
    first?

    Thanks.
    -cjl
     
    John, Jul 30, 2004
    #1
    1. Advertising

  2. John wrote:
    > In the course of an assignment, I learned the hard way that I shouldn't try
    > to free a malloc'd member of a malloc'd structure after having freed that
    > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    >
    > My question is, if I free just the structure, will the (e.g.) bufferspace be
    > freed implicitly, or do I have to (as I currently am) free the members
    > first?


    Free the members first. Information about subsequent allocation of
    members is not magically incoded into the information about the
    structure allocation.
     
    Martin Ambuhl, Jul 30, 2004
    #2
    1. Advertising

  3. John wrote on 30/07/04 :
    > In the course of an assignment, I learned the hard way that I shouldn't try
    > to free a malloc'd member of a malloc'd structure after having freed that
    > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    >
    > My question is, if I free just the structure, will the (e.g.) bufferspace be
    > freed implicitly, or do I have to (as I currently am) free the members
    > first?


    "All what have been done must be undone".

    IOW, yes, you have to free the innermost elements first. There is no
    implicit automatic mecanism that frees the memory in C.

    That said, you can write a pair of function known as 'creator /
    destructor' that helps to create / delete the objects properly and hide
    some gory details the user is not supposed to deal with.

    myobj_s *myobj_create (void);
    void myobj_delete (myobj_s *this);

    --
    Emmanuel
    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html

    "C is a sharp tool"
     
    Emmanuel Delahaye, Jul 30, 2004
    #3
  4. Martin Ambuhl wrote:

    > John wrote:
    > > In the course of an assignment, I learned the hard way that I shouldn't try
    > > to free a malloc'd member of a malloc'd structure after having freed that
    > > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    > >
    > > My question is, if I free just the structure, will the (e.g.) bufferspace be
    > > freed implicitly, or do I have to (as I currently am) free the members
    > > first?

    >
    > Free the members first. Information about subsequent allocation of
    > members is not magically incoded into the information about the
    > structure allocation.


    Ah, but what if some other structure is also pointing to one of those members? Do
    you keep a count of the number of items pointing to that member, and decrement
    when you might free it until it reaches 0, then free it?...
     
    Wayne Rasmussen, Jul 30, 2004
    #4
  5. John

    Malcolm Guest

    "Wayne Rasmussen" <> wrote
    >
    > Ah, but what if some other structure is also pointing to one of those
    > members? Do you keep a count of the number of items pointing to that
    > member, and decrement when you might free it until it reaches 0, then free
    > it?...
    >

    You've got to be disciplined. The general rule is that only one pointer
    should exist in long-term storage (obviously you must take copies to pass to
    subroutines, or for local manipulations).
    With some data structures, like linked lists, this isn't possible.
    Inherently there are two pointers to each node of a doubly-linked list. So
    you must define an object as "my doubly linked list data structure" and then
    write functions which will manipulate it, and especially destroy it, in a
    controlled way. Once the list is destroyed, all the pointers to data nodes
    should go with it.
     
    Malcolm, Jul 30, 2004
    #5
  6. John

    Alan Balmer Guest

    On 30 Jul 2004 13:43:38 EDT, Wayne Rasmussen
    <> wrote:

    >
    >
    >Martin Ambuhl wrote:
    >
    >> John wrote:
    >> > In the course of an assignment, I learned the hard way that I shouldn't try
    >> > to free a malloc'd member of a malloc'd structure after having freed that
    >> > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    >> >
    >> > My question is, if I free just the structure, will the (e.g.) bufferspace be
    >> > freed implicitly, or do I have to (as I currently am) free the members
    >> > first?

    >>
    >> Free the members first. Information about subsequent allocation of
    >> members is not magically incoded into the information about the
    >> structure allocation.

    >
    >Ah, but what if some other structure is also pointing to one of those members? Do
    >you keep a count of the number of items pointing to that member, and decrement
    >when you might free it until it reaches 0, then free it?...
    >

    Well, first you review your design, because there is probably a better
    way to do it ;-)

    But if you must, yes, reference counters are a common way to handle
    the situation.

    --
    Al Balmer
    Balmer Consulting
     
    Alan Balmer, Jul 30, 2004
    #6
  7. Alan Balmer wrote:

    > On 30 Jul 2004 13:43:38 EDT, Wayne Rasmussen
    > <> wrote:
    >
    > >
    > >
    > >Martin Ambuhl wrote:
    > >
    > >> John wrote:
    > >> > In the course of an assignment, I learned the hard way that I shouldn't try
    > >> > to free a malloc'd member of a malloc'd structure after having freed that
    > >> > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    > >> >
    > >> > My question is, if I free just the structure, will the (e.g.) bufferspace be
    > >> > freed implicitly, or do I have to (as I currently am) free the members
    > >> > first?
    > >>
    > >> Free the members first. Information about subsequent allocation of
    > >> members is not magically incoded into the information about the
    > >> structure allocation.

    > >
    > >Ah, but what if some other structure is also pointing to one of those members? Do
    > >you keep a count of the number of items pointing to that member, and decrement
    > >when you might free it until it reaches 0, then free it?...
    > >

    > Well, first you review your design, because there is probably a better
    > way to do it ;-)
    >
    > But if you must, yes, reference counters are a common way to handle
    > the situation.


    Sure, good design should be done first. But this is more of the what if variety.
    Actually, was curious to see other ways people might deal with this. Other than good
    design, what would be the other common ways? Having a master array of that type for
    example.

    Not looking to create a garage collector either!


    cya,
    wayne
     
    Wayne Rasmussen, Jul 30, 2004
    #7
  8. Malcolm wrote:

    > "Wayne Rasmussen" <> wrote
    > >
    > > Ah, but what if some other structure is also pointing to one of those
    > > members? Do you keep a count of the number of items pointing to that
    > > member, and decrement when you might free it until it reaches 0, then free
    > > it?...
    > >

    > You've got to be disciplined. The general rule is that only one pointer
    > should exist in long-term storage (obviously you must take copies to pass to
    > subroutines, or for local manipulations).
    > With some data structures, like linked lists, this isn't possible.
    > Inherently there are two pointers to each node of a doubly-linked list. So
    > you must define an object as "my doubly linked list data structure" and then
    > write functions which will manipulate it, and especially destroy it, in a
    > controlled way. Once the list is destroyed, all the pointers to data nodes
    > should go with it.


    Well, doubly linked lists are a special case for sure.

    I was trying to think of a good example, like say a chess board where you would
    want to try some search with alpha-beta and backtracking. But in those cases,
    you really should be making copies of game board and everything it refers to or
    at least, have a way to get back to the previous position when backtracking.

    Then I was thinking of a DB, where you might have different links say to a
    zipcode table record, but ideally there should be one path to get to that
    information should there?

    If you were doing your own garbage collector you might have to worry about this.
     
    Wayne Rasmussen, Jul 30, 2004
    #8
  9. John

    Karthik Guest

    John wrote:

    > In the course of an assignment, I learned the hard way that I shouldn't try
    > to free a malloc'd member of a malloc'd structure after having freed that
    > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    >
    > My question is, if I free just the structure, will the (e.g.) bufferspace be
    > freed implicitly, or do I have to (as I currently am) free the members
    > first?


    huh, if only that was true (freeing members implicitly), there
    would be less memory leaks on earth. Unfortunately it is not true.

    You got two problems:-
    smaller one: your memory access is likely to cause seg. fault ( you are
    going out of the address space of the process).

    bigger one: memory leak.

    Pointer is nothing but a variable that stores an address. The
    moment you do a free(structure), the memory pointed to by that address
    is reclaimed by the GC ( in other words, that could be used again by the
    memory manager in the future). But the info. to delete
    sturucture->bufferspace has already been freed by your previous
    statement. So you won't find the address that ought to be removed as far
    as 'structure->bufferspace' is concerned.


    Try to group the malloc/free in a function as far as possible. It
    would help you to get rid of memory leaks ( and anyone who had to
    read/maintain would be thankful to you for that).

    HTH.

    - Karthik.
     
    Karthik, Jul 31, 2004
    #9
  10. John

    Stan Milam Guest

    Wayne Rasmussen wrote:

    >
    > Martin Ambuhl wrote:
    >
    >
    >>John wrote:
    >>
    >>>In the course of an assignment, I learned the hard way that I shouldn't try
    >>>to free a malloc'd member of a malloc'd structure after having freed that
    >>>structure (i.e., free( structure ); free( structure->bufferspace ) ).
    >>>
    >>>My question is, if I free just the structure, will the (e.g.) bufferspace be
    >>>freed implicitly, or do I have to (as I currently am) free the members
    >>>first?

    >>
    >>Free the members first. Information about subsequent allocation of
    >>members is not magically incoded into the information about the
    >>structure allocation.

    >
    >
    > Ah, but what if some other structure is also pointing to one of those members? Do
    > you keep a count of the number of items pointing to that member, and decrement
    > when you might free it until it reaches 0, then free it?...



    In my humble opinion having foriegn structure members point to other
    structure members is just bad programming design. Loose coupling and
    tight cohesiveness is not only desirable for coded functions, but for
    data too. As to the issue of freeing malloc'd members I would suggest,
    at the very least, to have a dedicated function to free all the members,
    then free the structure last of all.

    Regards,
    Stan Milam.
     
    Stan Milam, Jul 31, 2004
    #10
  11. John

    Flash Gordon Guest

    On 30 Jul 2004 18:34:15 EDT
    Wayne Rasmussen <> wrote:

    > Alan Balmer wrote:


    <snip freeing malloced space>

    > > Well, first you review your design, because there is probably a
    > > better way to do it ;-)
    > >
    > > But if you must, yes, reference counters are a common way to handle
    > > the situation.

    >
    > Sure, good design should be done first. But this is more of the what
    > if variety. Actually, was curious to see other ways people might deal
    > with this. Other than good design, what would be the other common
    > ways? Having a master array of that type for example.
    >
    > Not looking to create a garage collector either!


    The best way of dealing with this depends on the problem being solved
    and the design of the SW, so the only way to handle it reliably is with
    good SW design. IMHO any other method leads to bugs and/or madness.

    In general you need some easily determined relationship between the
    point at which the space is allocated, when it is used and when it is
    freed. Normally I go for a single pointer to either the data or to the
    root of a tree or list of some form. Sometimes I would consider a
    reference counter, but not very often. Always when it is a complex
    situation (reference counts, linked lists, trees etc.) use a library to
    maintain the structure and have a single master record (e.g. the pointer
    to the root of a tree).
    --
    Flash Gordon
    Sometimes I think shooting would be far too good for some people.
    Although my email address says spam, it is real and I read it.
     
    Flash Gordon, Jul 31, 2004
    #11
  12. John

    Malcolm Guest

    "Stan Milam" <> wrote in message
    >
    > In my humble opinion having foriegn structure members point to other
    > structure members is just bad programming design. Loose coupling and
    > tight cohesiveness is not only desirable for coded functions, but for
    > data too. As to the issue of freeing malloc'd members I would suggest,
    > at the very least, to have a dedicated function to free all the members,
    > then free the structure last of all.
    >

    You're right, but the problem is that the ideal design isn't always easy to
    come up with.
    Let's say we have a video game with rats running about a maze. You will need
    a structure for each cell of the maze, with a pointer to the rats. However
    it is also very handy to have a list of rats, without iterating over every
    cell of the maze, and each rat probably needs a pointer to the cell of the
    maze that it is in. So we end up with a non-ideal situation of several
    pointers in different structures pointing to the same thing.
     
    Malcolm, Jul 31, 2004
    #12
  13. John

    Dag Viken Guest

    "John" <> wrote in message
    news:...
    > In the course of an assignment, I learned the hard way that I shouldn't

    try
    > to free a malloc'd member of a malloc'd structure after having freed that
    > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    >
    > My question is, if I free just the structure, will the (e.g.) bufferspace

    be
    > freed implicitly, or do I have to (as I currently am) free the members
    > first?
    >
    > Thanks.
    > -cjl
    >
    >

    Yes, free() any members that have been malloc()'ed first.
    This is why C++ has destructors!
     
    Dag Viken, Jul 31, 2004
    #13
  14. John

    pete Guest

    John wrote:
    >
    > In the course of an assignment, I learned the hard way that I shouldn't try
    > to free a malloc'd member of a malloc'd structure after having freed that
    > structure (i.e., free( structure ); free( structure->bufferspace ) ).
    >
    > My question is, if I free just the structure,
    > will the (e.g.) bufferspace be freed implicitly,


    It will not be freed implicitly.

    > or do I have to (as I currently am) free the members first?


    Sometimes you don't want to.
    You might have lists of lists.
    Say for example, a list of people's characteristics in nodes,
    and each person node has a list of some friend's names.
    If you have John Smith with a friend's name in one list
    and the same John Smith with two friends' names in another list,
    Then you might want to combine the two lists of people's
    characteristics in such a way that the two lists of friends'
    names are combined into one list on the first John Smith node
    while the second John Smtih node is freed,
    leaving it's member list attached to the first John Smith node.

    When the time comes to free the big list, though,
    the member lists will need to be freed first.

    --
    pete
     
    pete, Aug 2, 2004
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ravi
    Replies:
    0
    Views:
    471
  2. Bernard Liang

    sscanf'ing floats into structure members

    Bernard Liang, Jun 21, 2006, in forum: C Programming
    Replies:
    3
    Views:
    723
    Keith Thompson
    Jun 21, 2006
  3. jbholman
    Replies:
    19
    Views:
    939
    CBFalconer
    Sep 19, 2008
  4. Replies:
    0
    Views:
    417
  5. arnuld
    Replies:
    13
    Views:
    532
    Ben Pfaff
    Apr 14, 2009
Loading...

Share This Page