By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,300 Members | 1,789 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,300 IT Pros & Developers. It's quick & easy.

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

P: n/a
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
Nov 14 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
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.
Nov 14 '05 #2

P: n/a
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"

Nov 14 '05 #3

P: n/a


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?...
Nov 14 '05 #4

P: n/a

"Wayne Rasmussen" <Xv*****************@gomonarch.com> 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.
Nov 14 '05 #5

P: n/a
On 30 Jul 2004 13:43:38 EDT, Wayne Rasmussen
<Xv*****************@gomonarch.com> 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
re************************@att.net
Nov 14 '05 #6

P: n/a


Alan Balmer wrote:
On 30 Jul 2004 13:43:38 EDT, Wayne Rasmussen
<Xv*****************@gomonarch.com> 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

Nov 14 '05 #7

P: n/a


Malcolm wrote:
"Wayne Rasmussen" <Xv*****************@gomonarch.com> 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.

Nov 14 '05 #8

P: n/a
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.
Nov 14 '05 #9

P: n/a
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.
Nov 14 '05 #10

P: n/a
On 30 Jul 2004 18:34:15 EDT
Wayne Rasmussen <Xv*****************@gomonarch.com> 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.
Nov 14 '05 #11

P: n/a

"Stan Milam" <st*****@swbell.net> 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.
Nov 14 '05 #12

P: n/a
"John" <ia******@hotmail.com> wrote in message
news:gZ********************@comcast.com...
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!
Nov 14 '05 #13

P: n/a
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
Nov 14 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.