473,836 Members | 1,935 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Freeing memory for nested structures

Hi again,

one of the other big woes I'm having...

typedef struct perBlockStru /* (structure) Long words per block
*/
{
unsigned long *lword[LASTLW];
} lwperBlockStru_ t;

typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;

This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.

Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)
for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d long));
...
}
}

At the VERY bottom, shortly before exiting the app, I *thought* I could just
do:

if (pE != NULL)
free(pE);

Preposterously, it sometimes does work, but sometimes I also get a GPF.
Hence I assume that I am required to go the "awkward" way by using another
loop
in the destruction routine.
Or is this supposed to work by simply using the free routine from the
structure's base address?

-Andreas

Oct 28 '08 #1
25 4743

"Andreas Eibach" <ae*****@mail.c omwrote in message
Hi again,

one of the other big woes I'm having...

typedef struct perBlockStru /* (structure) Long words per
block
*/
{
unsigned long *lword[LASTLW];
} lwperBlockStru_ t;

typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;

This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.

Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)
for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d long));
...
}
}

At the VERY bottom, shortly before exiting the app, I *thought* I could
just
do:

if (pE != NULL)
free(pE);

Preposterously, it sometimes does work, but sometimes I also get a GPF.
Hence I assume that I am required to go the "awkward" way by using another
loop
in the destruction routine.
Or is this supposed to work by simply using the free routine from the
structure's base address?
Write a "kill" function.

void killentity_Stru _t(entity_Stru_ t *e)
{
int i, ii;

if(e)
{
for(i=0;i<LASBL K;i++)
for(ii=0;ii<LAS TLW;ii++)
free(e->block[i]->word[ii]):
free(e);
}
}

I think I've got this right. It becomes boilerplate code after a while. More
modern languages with garbage collection automate the process for you, but
in C you have to free everything by hand. Think of it as a little chore.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 28 '08 #2
"Andreas Eibach" <ae*****@mail.c omwrites:
Hi again,

one of the other big woes I'm having...

typedef struct perBlockStru /* (structure) Long words per block
*/
{
unsigned long *lword[LASTLW];
} lwperBlockStru_ t;

typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;

This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.

Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)
pE = &entityStru_ t , I assume.

By the way, if this is a Unix/POSIX system, AFAIK you are not supposed
to name things ending in _t ; they're reserved for the system.
for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d long));
I presume this is not your actual code, and that you really have
malloc(sizeof(u nsigned long) * n) to allocate an array of n unsigned
longs. Allocating just one seems kind of weird, I suspect it wouldn't
be what you'd want.
...
}
}

At the VERY bottom, shortly before exiting the app, I *thought* I could just
do:

if (pE != NULL)
free(pE);
No. You must pass to free() exactly those pointers that were returned
from malloc(), and nothing else. free() does not know about your more
elaborate data structure and cannot dig down into it to find the things
you malloc'ed.
Preposterously, it sometimes does work, but sometimes I also get a GPF.
Hence I assume that I am required to go the "awkward" way by using another
loop
in the destruction routine.
Right.

However, if this really is right before exiting, it is probably not
necessary to free this stuff at all, as any sane operating system will
take care of it for you. See http://c-faq.com/malloc/freeb4exit.html .
It might still be a good idea to do it for maintainability reasons,
depending on your situation.
Or is this supposed to work by simply using the free routine from the
structure's base address?
No.
Oct 28 '08 #3
Andreas Eibach wrote:
Hi again,

one of the other big woes I'm having...

typedef struct perBlockStru /* (structure) Long words per block
*/
{
unsigned long *lword[LASTLW];
} lwperBlockStru_ t;

typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;

This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.

Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)
What you wrote is nonsense. I suspect that what you were trying to say
would be correctly expressed as:

entityStru_t *pE;
for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d long));
...
}
}

At the VERY bottom, shortly before exiting the app, I *thought* I could just
do:

if (pE != NULL)
free(pE);

Preposterously, it sometimes does work, but sometimes I also get a GPF.
You don't show us the code whereby pE acquires a value, so it's hard
to tell whether or not you should be able to safely call free(pE).
However, if you don't want to leak memory, you had better free(pE-
>block[i]->lword[j]) for all relevant values of "i" and "j", before
free()ing pE itself.
Hence I assume that I am required to go the "awkward" way by using another
loop
in the destruction routine.
Or is this supposed to work by simply using the free routine from the
structure's base address?
Was the memory for the structure itself allocated using malloc(),
calloc() or realloc()? You show no such allocation, so there's no way
for us to be sure. If it was, it can be free()d.
Oct 28 '08 #4

"Malcolm McLean" <re*******@btin ternet.comwrote :
Write a "kill" function.

void killentity_Stru _t(entity_Stru_ t *e)
{
int i, ii;

if(e)
{
for(i=0;i<LASBL K;i++)
for(ii=0;ii<LAS TLW;ii++)
free(e->block[i]->word[ii]):
free(e);
}
}

I think I've got this right.
Indeed you got, yet when I asked, "do I have to go the awkward way", even
mentioning the word "loop" in the very same breath, I _had_ thought that the
readers will realize I do know *how* to do that :-)
But if I hate something it's trial-and_error beyond some certain extent;
hence I was just reflecting upon what I would start coding next ...
It becomes boilerplate code after a while. More
modern languages with garbage collection automate the process for you, but
in C you have to free everything by hand.
Well, I do know it that far. But I did not know *how* deeply (i. e. whether
C would "know" about sub-structures and stuff simply by creating a complex
chain of storage addresses or so---in this case, the base address would have
been sufficient; but apparently it does not)
>Think of it as a little chore.
Yes, thank you. So the loop thing has to do the trick then. :)

-Andreas

Oct 28 '08 #5
Andreas Eibach wrote:
Hi again,

one of the other big woes I'm having...

typedef struct perBlockStru /* (structure) Long words per block
*/
{
unsigned long *lword[LASTLW];
} lwperBlockStru_ t;

typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;

This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.

Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)
for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
These loops look pretty strange. I *really* wish people with
code problems would post the actual code they're having trouble
with, and not "sort of like" paraphrases. We wind up debugging the
problems of the paraphrase, and not the actual problem -- which may
not even be present in the paraphrase.
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d long));
Case in point: We can guess what the loops were supposed to be,
and we've been told that `pE' is a pointer to an entityStru_t, but
there's nothing to show us (1) how memory was allocated for `pE' to
point at, nor (2) how memory was allocated for each `pE->block[i]'.
Since your *entire* question is about memory management, hiding these
details behind a laconic "..." is not especially helpful. I can make
a lot of guesses about what the "..." might be concealing, but there's
no way for me to actually know what you've done wrong. Oh, sorry,
that last word is just a guess ...
...
}
}

At the VERY bottom, shortly before exiting the app, I *thought* I could just
do:

if (pE != NULL)
free(pE);
The test is harmless, but unnecessary.
Preposterously, it sometimes does work, but sometimes I also get a GPF.
Preposterously you haven't explained what you mean by "work," nor
what leads you to believe that it "worked."
Hence I assume that I am required to go the "awkward" way by using another
loop
in the destruction routine.
Or is this supposed to work by simply using the free routine from the
structure's base address?
The general rule: For each call malloc() there's a corresponding
call to free(). This isn't quite right all the time: You might allocate
something and just leave it allocated until program end, or you might
mix calloc() and realloc() into the picture. But the main observation
remains: One call to free() will not magically release memory obtained
from multiple calls to malloc().

--
Er*********@sun .com
Oct 28 '08 #6

"Nate Eldredge" <na**@vulcan.la nschrieb im Newsbeitrag
news:86******** ****@vulcan.lan ...
"Andreas Eibach" <ae*****@mail.c omwrites:
Hi again,

one of the other big woes I'm having...

typedef struct perBlockStru /* (structure) Long words per
block
*/
{
unsigned long *lword[LASTLW];
} lwperBlockStru_ t;

typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;

This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.

Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)

pE = &entityStru_ t , I assume.
yep.

entityStru_t * pE was the declaration, I'm often confusing them when I have
to word them, but I seem to have made it correctly, as pE->... does indeed
"find" the structure members ;-)
By the way, if this is a Unix/POSIX system, AFAIK you are not supposed
to name things ending in _t ; they're reserved for the system.
Heheh, yes it's a habit.

for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d
long));
>
I presume this is not your actual code,
You're right about that it's shortened a lot.
and that you really have
malloc(sizeof(u nsigned long) * n) to allocate an array of n unsigned
longs.
Eh? I have a LASTLW amount of longs, and LASTLW is a #define'd constant, e.
g. 64. I do not use "hard-coded" numbers, it's a habit (but a good one this
time, I guess :))
Allocating just one seems kind of weird, I suspect it wouldn't
be what you'd want.
But I'm allocating LASTLW ones in a loop, you did notice the for() loop,
didn't you?
Come to think of it, I could get rid of the for loop and use n times the
ULONGs in the malloc, if that is what you mean.
free() does not know about your more
elaborate data structure and cannot dig down into it to find the things
you malloc'ed.
Yes, that was my suspicion and the same what Malcolm already pointed out.
Thanks to the both of you.
However, if this really is right before exiting, it is probably not
necessary to free this stuff at all [...]
It might still be a good idea to do it for maintainability reasons,
depending on your situation.
I'd always do it. Period. Never "rely" on how well the garbage collection
works.
(except for JAVA, the GC of which I do fully trust)

-Andreas

Oct 28 '08 #7
Andreas Eibach wrote:
....
But if I hate something it's trial-and_error beyond some certain extent;
You should hate it a whole lot more than you apparently do. When we're
talking about programming languages, the space you explore by trial
and error has both an huge volume and a very high dimensionality. It's
easy to get thoroughly lost in that space, and very difficult to find
out anything useful that way; finding what you're actually looking for
is practically impossible by that method. Reading the documentation,
reading text books, and asking for advice is the right way to go about
it.

....
Well, I do know it that far. But I did not know *how* deeply (i. e. whether
C would "know" about sub-structures and stuff simply by creating a complex
chain of storage addresses or so---in this case, the base address would have
been sufficient; but apparently it does not)
It doesn't matter what C "knows". What free(expression ) is supposed to
do, if "expression " is not a null pointer, is to release the memory
pointed at by "expression "; something it can do if "expression " has a
value that matches one returned by a previous call to malloc(),
calloc() or realloc(). The behavior is undefined if you pass it any
other pointer value. It free()s the memory that was allocated by that
previous call - nothing more, nothing less.
Oct 28 '08 #8
On Tue, 28 Oct 2008 21:32:40 +0100, "Andreas Eibach"
<ae*****@mail.c omwrote:
>Hi again,

one of the other big woes I'm having...

typedef struct perBlockStru /* (structure) Long words per block
*/
{
unsigned long *lword[LASTLW];
} lwperBlockStru_ t;

typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;

This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.

Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)
for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d long));
...
}
}

At the VERY bottom, shortly before exiting the app, I *thought* I could just
do:

if (pE != NULL)
free(pE);

Preposterously , it sometimes does work, but sometimes I also get a GPF.
Hence I assume that I am required to go the "awkward" way by using another
loop
in the destruction routine.
Or is this supposed to work by simply using the free routine from the
structure's base address?
Unfortunately, no. The rule is very simple; you need one call to
free for each call to malloc.

I assume that your sample code has typos, and that you really
mean to loop through the outer loop LASTBLK times and the inner
loop LASTLW times.

There are a number of things that you can do to decrease the
number of calls to malloc that you will need. In essence the
idea is to allocate a large block that holds many small blocks.
Here is an example:

Allocate a large block of longs, e.g.,

many_longs = malloc(LASTBLK* LASTLW*sizeof(l ong));
...
k = 0;
for (i=0;i<LASTBLK; i++) {
...
for (j=0; j<LASTLW;j++) {
pE->block[i]->lword[j] = many_longs + k++;
...
}
}

Incidentally, it seems rather odd that lword[j] is a pointer to a
long rather than simply a long. Did you mean to do this?

Richard Harter, cr*@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
Oct 28 '08 #9
Andreas Eibach wrote:
"Nate Eldredge" <na**@vulcan.la nschrieb im Newsbeitrag
news:86******** ****@vulcan.lan ...
"Andreas Eibach" <ae*****@mail.c omwrites:
....|
typedef struct Entity /* (structure) Holds the whole thing */
{
perBlockStru_t* block[LASTBLK];
} entityStru_t;
>
This is a - fairly simplified - structure I'm using.
Of course there are more elements, but they are irrelevant here.
>
Far below, there's the obvious mem allocation happening:
(pE = *entityStru_t)
pE = &entityStru_ t , I assume.

yep.
That still doesn't work. entitStru_t is a typedef for "struct
Entity". 6.5.3.2p1 says "The operand of the unary & operator shall be
either a function designator, the result of a [] or unary * operator,
or an lvalue that designates an object that is not a bit-field and is
not declared with the register storage-class specifier." The type
"struct Entity" fits none of those categories.
entityStru_t * pE was the declaration, I'm often confusing them when I have
to word them, but I seem to have made it correctly, as pE->... does indeed
"find" the structure members ;-)
Yes, but the code you've decided to not bother posting leaves us still
in the dark as to how the value of 'pE' is set. This is a critical
point in deciding whether or not your call to free() should actually
work.
for (i 0; i = LASTBLK; i++)
{ ...
for (j= 0; j = LASTLW; j++)
{ ...
pE->block[i]->lword[j] = malloc (sizeof(unsigne d
long));

I presume this is not your actual code,

You're right about that it's shortened a lot.
It's not just shortened, it's wrong. As written, both the inner and
outer loops are infinite, unless LASTBLK or LASTLW happens to be 0, in
which case the relevant loop doesn't execute at all. Re-check your
loop conditions.

....
Allocating just one seems kind of weird, I suspect it wouldn't
be what you'd want.

But I'm allocating LASTLW ones in a loop, you did notice the for() loop,
didn't you?

Come to think of it, I could get rid of the for loop and use n times the
ULONGs in the malloc, if that is what you mean.
Yes, that's precisely what you should be doing. There's usually a
small memory overhead, and a large time overhead, associated with
every call to malloc().
Oct 28 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
22980
by: disco | last post by:
I am working on this example from a book "C Primer Plus" by Prata 4th edition - p. 672. There is no erata on this problem at the publisher's website. 1) Is it a violation of copyright laws to post example code from a book to a newsgroup? 2) The program crashes as it tries to free memory and I would like to know the best way to correct THIS section of the code. By assigning current = head, current now points to the first structure in...
12
3079
by: f.oppedisano | last post by:
Hi, i would like to allocate two structures making only one malloc call. So i do prt=malloc(sizeof(struct1)+sizeof(struct2)); After this operation i make two pointers one to the first struct (ptr1=ptr), the other to second struct(ptr2=ptr+sizeof(struct2)). These two pointer are later used by two threads in mutual exclusion so thread1 can't access ptr2 and thread2 can't access ptr1. At some time thread2 wants to free his part of memory but...
9
1959
by: Alfonso Morra | last post by:
Hi, I am having some probs with copying memory blocks around (part of a messaging library) and I would like some confirmation to make sure that I'm going about things the right way. I have some data types defined thus: typedef enum { ONE ,
15
1774
by: yehoshua | last post by:
Is there anyway to explicitly tell the garbage collector you are done with an object? In my app I have a point where I am sure there should be no references to an set of objects (well i remove what i assume is the last reference to them) and I want them to be GCed. But for some reason my app is leaking memory and that is the only place I can think of that something could be going wrong. I want to just say...
94
4790
by: smnoff | last post by:
I have searched the internet for malloc and dynamic malloc; however, I still don't know or readily see what is general way to allocate memory to char * variable that I want to assign the substring that I found inside of a string. Any ideas?
171
4969
by: Raman | last post by:
Hi All, Here is a small Code, int main(void) { char *p=(char *) malloc(100); strcpy(p,"Test1234567890"); p=p+10; free(p);
3
6682
by: Amit_Basnak | last post by:
Dear Friends I have the follwoing function "tss_fe_get_own_info" which has the arguments as shows below tss_fe_get_own_info(char *user_id, tss_user_profile_t **p_buf_UserSecInfo, error_status_t *retStatus) // Structure tss_user_profile_t from the function typedef struct {
6
2040
by: Praetorian | last post by:
This is actually 2 questions: The first one: I have a function (FuncA) calling another (FuncB) with a set of parameters which also includes an int * initialized to NULL before the call. Now FuncB looks at the other parameters and decides whether or not to allocated memory to the int * passed to it (using calloc()). One of the other parameters passed is a structure and if FuncB does allocate memory it'll point one of the members of this...
11
2015
by: vivek | last post by:
Hello, I have a pointer to a main structure which again consists of structures, enums, char, int, float and again complex structures. When i free all the contents of the main structure, it takes me a lot of time (since i have to loop determining the data type and freeing it). Is there any idea to free all the contents of the structure in shortest possible time.
0
9812
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
10533
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10579
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10244
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6975
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5644
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4443
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4003
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3103
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.