Re: GSList and g_filename_from_uri free memory problem




On Thu 02/23, Colossus wrote:

you must pass the list's head node pointer to g_slist_free(), which
you will lost if you use Files_to_Add directly (in fact, it will
always be null after the while loop)
Thank you all, I discovered a memory leak in my code. I was not
freeing the data pointer inside the GSList. Long life to GTK+2 !!!

You sound like you've got it sorted...  But just in case...  And incase anyone else is in the same position, 
I'll run over the topic in a different (and somewhat longer ;) ) way to any of the replies that I've seen so 
far.

You started off with a chunk of memory holding a URI.  You handed that memory to the filename_from_uri 
function, which didn't take ownership, but instead creates a bit of memory to put the extracted filename into 
(presumably, so as not to disrupt the existing URL).  This new piece of memory, is at this stage owned by the 
filename_from_uri function.

It gives you the memory (a pointer to it), which you generally store in a character pointer variable while 
you work on it or whatever.  Now you own it.  Since you own it, it's your responsibility to free it when 
you're done with it (but not before).

You then hand that chunk of memory (without regard to what it is) to the GSList.  Like you did with the 
memory returned by the function, GSList takes ownership of that memory from you, so you no longer have to 
worry about freeing it (unlike the original function which just looks at the memory you gave it, without 
actually taking ownership).

Once you've given the memory over to GSList, it's owned by GSList until such time as you take it back.  And 
therefore, it's not your responsibility to free it so long as GSList owns it.

However, the catch comes when you want to destroy the GSList, since a GSList doesn't know what it is holding. 
 It's composed of a bunch of chunks of memory (which it owns), contained within is a space made available for 
you to place a piece of data (in this case, memory that you owned, but have handed to it for safe keeping -- 
so now it owns it).  But in the end, all GSList is doing, is holding a number which it assumes is a pointer 
to some piece of memory.  But for all it knows, it could be an integer value that's been cast into a pointer 
to fit the space it's offering, or a whole GObject or widget or something that needs special attention to 
free it.  Since the GSList doesn't know what it's holding, it can't free it -- therefore, YOU have to take 
ownership back, before you destroy the list.

The easiest way to do that, is to iterate over the list, take back ownership the data pointers (your 
filenames) one by one (essentially a conceptual transition, no function call or anything), and free them one 
by one as you walk the list.  Once that's done, you've got a still fully intact GSList which doesn't own 
anything but its own internal memory (the data pointers are now invalid, since you took back ownership of the 
memory and free'd it, but they're all still otherwise there).  So you can go ahead and tell it to free itself.

The easiest way to handle destroying a GSList containing g_malloc()'d memory (such as strings containing 
filenames), is with a little helper function that just iterates over the list g_free()'ing everything, and 
then destroys the list itself.  I think GSList's have a foreach style function which does the iterating for 
you, so you can probably even get away with calling that with g_free() as your callback function.  But in any 
case, in a nice neat three-line function, you can free all the data being held by the GSList, and then 
destroy the list itself.  Call it gslist_destroy_with_free() or something handy like that.


Fredderic

_______________________________________________
Join Excite! - http://www.excite.com
The most personalized portal on the Web!





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]