Chaînes C/Glib qui doivent être libérées par l'appelant
Question
J'utilise désinvolte,
il a beaucoup de fonctions qui renvoient des chaînes qui devraient être libérées moi-même.
Puis-je transmettre ces fonctions à d’autres fonctions ?
Exemple: fonction1 renvoie une chaîne qui doit être libérée pour l'appelant.fonction2 renvoie un pointeur vers une chaîne qui doit également être libérée.
gchar *string = function2(function1("something"));
g_free (string);
Comment dois-je libérer la chaîne renvoyée par la fonction1 ?Est-ce nécessaire ?
Merci beaucoup,
et désolé pour mon anglais
La solution
Oui il faut libérer la chaîne renvoyée par function1
.Pour vous permettre de faire cela, vous devez prendre une copie de la valeur de retour :-
gchar* temp = function1("something");
gchar* string = function2(temp);
g_free(temp);
g_free(string);
Autres conseils
Dans l'exemple que tu donnes :
gchar *string = function2(function1("something"));
g_free (string);
Toi ne peut pas libérer la chaîne de function1()
.Il s'agit d'une fuite de mémoire.Donc, même si je sais que c'est bien de compresser les choses, vous devriez ralentir :
gchar *temp, *string;
temp = function1("something");
string = function2(temp);
g_free(temp);
temp = NULL;
g_free(string);
Sinon, chaque fois que ce code s'exécute, function1()
allouera plus de mémoire qui ne sera jamais libérée, et si votre application s'exécute pendant une longue période, votre programme commencera lentement à manquer de mémoire disponible (à cause de toute cette mémoire allouée qui n'est jamais free()
d).
Une autre alternative consiste à écrire un wrapper autour function2()
:
gchar *function2_wrapper(gchar *c)
{
gchar *ret = function2(c);
free(c);
return ret;
}
gchar *string = function2_wrapper(function1("something"));
Mais à mon avis, cela demande probablement plus d'efforts que cela n'en vaut la peine, et quiconque regarde votre code risque d'être perdu, de penser qu'il y a une fuite de mémoire alors qu'il n'y en a pas, de le réécrire et d'être frappé par un double-free()
erreur au moment de l'exécution et je n'ai aucune idée de ce qui se passe,
Oui, c'est vrai, comme le sont @DaveRigby et d'autres pointu out, que vous devez obtenir la valeur du pointeur renvoyée par function1()
pour le libérer.Mais il y a du gros si!
Si vous faites référence à des fonctions simples comme g_string_append()
comme function1()
, tu devrais pas libérez-le.Parce que ces fonctions renvoient ce que vous avez transmis.
Disons que vous avez
GString *s = g_string_new("foo");
et tu veux avoir "http://foo/bar"
, tu peux faire:
s = g_string_prepend(g_string_append(s, "/bar"), "http://");
use_my_string(s);
g_string_free(s);
Je sais que l’exemple ci-dessus n’est pas le meilleur, mais j’espère que vous comprendrez l’intérêt.Les fonctions GString peuvent être dites destructeur.Il ne crée pas de copie des chaînes données.