473,398 Members | 2,120 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

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

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
13 7258
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
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


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

"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
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


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


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
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
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
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

"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
"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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Chris Potter | last post by:
Hello everyone. I have two questions both of which regard a homework assignment for my "Intro to C" class. The First question that i have is that my program segfaults when i free() memory that i...
74
by: Suyog_Linux | last post by:
I wish to know how the free()function knows how much memory to be freed as we only give pointer to allocated memory as an argument to free(). Does system use an internal variable to store allocated...
6
by: Code Raptor | last post by:
Folks, I am hitting a segfault while free()ing allocated memory - to make it short, I have a linked list, which I try to free node-by-node. While free()ing the 28th node (of total 40), I hit a...
7
by: slashdotcommacolon | last post by:
Hello, I'm working on the exercises from k&r, exercise 5-13 is to implement a simple replacement for the unix tail command. The brief says it should be able to cope no matter how unreasonable the...
7
by: Jack | last post by:
how does free know how much of memory to release if I say free(ptr)? Thanks.
3
by: Bartholomew Simpson | last post by:
I am writing some C++ wrappers around some legacy C ones - more specifically, I am providing ctors, dtors and assignment operators for the C structs. I have a ton of existing C code that uses...
13
by: Chad | last post by:
Excercise 6-5 Write a functon undef that will remove a name and defintion from the table maintained by lookup and install. Code: unsigned hash(char *s); void undef(char *s)
6
Markus
by: Markus | last post by:
If we free() a pointer, is the pointer free()d or the memory the pointer points to? #include <stdlib.h> #include <stdio.h> #include "stack.h" void stack_new(stack *st) { st->log_len = 0;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.