Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/Glib Strings that should be freed by the caller

Tags:

c

glib

I am using glib,
it has a lot of functions that return strings that should be freed myself.

Can I, pass these functions to other functions?

Example: function1 returns a string that must be freed for the caller. function2 returns a pointer to a string that must be freed also.

gchar *string = function2(function1("something"));
g_free (string);

How should I free the string returned from function1? Is this necessary?

Thanks a lot,
and sorry for my english

like image 376
drigoSkalWalker Avatar asked Aug 18 '09 21:08

drigoSkalWalker


3 Answers

Yes it is necessary to free the string returned by function1. To allow you to do this, you need to take a copy of the return value :-

gchar* temp = function1("something");
gchar* string = function2(temp);
g_free(temp);
g_free(string);
like image 134
DaveR Avatar answered Nov 05 '22 08:11

DaveR


In the example you give:

gchar *string = function2(function1("something"));
g_free (string);

You can't free the string from function1(). This is a memory leak. So while I know it's nice to compress things, you should slow down:

gchar *temp, *string;
temp = function1("something");
string = function2(temp);
g_free(temp);
temp = NULL;
g_free(string);

Otherwise, every time that code runs, function1() will be allocating more memory that never gets freed, and if your application runs for a long time, your program will start slowly running out of avaliable memory (because of all that allocated memory that is never free()d).

Another alternative is to write a wrapper around function2():

gchar *function2_wrapper(gchar *c)
{
    gchar *ret = function2(c);
    free(c);
    return ret;
}

gchar *string = function2_wrapper(function1("something"));

But in my opinion that's probably more effort than it's worth, and anyone looking at your code may be lost, think there is a memory leak when there isn't, and rewrite it and get hit with a double-free() error at runtime and have no idea what's going on,

like image 43
Chris Lutz Avatar answered Nov 05 '22 06:11

Chris Lutz


Yes, it is true, as @DaveRigby and others are pointed out, that you need to get the pointer value returned from function1() to free it. But there is big if!

If you are referring glib functions like g_string_append() as function1(), you should not free it. Because those functions return what you passed on.

Let's say you have

GString *s = g_string_new("foo");

and you want to have "http://foo/bar", you can do:

s = g_string_prepend(g_string_append(s, "/bar"), "http://");
use_my_string(s);
g_string_free(s);

I know the above example is not the best one but hope you can see the point. GString functions can be said destructive. It does not create a copy of given strings.

like image 1
Yasushi Shoji Avatar answered Nov 05 '22 07:11

Yasushi Shoji