7 votes

Comment libérer correctement (et efficacement) la mémoire dans un widget gtk

J'essaie de comprendre comment libérer correctement la mémoire lorsque j'ai terminé avec un widget GTK, par exemple si je dois créer et détruire de nombreux widgets. Cependant, valgrind semble indiquer une fuite de mémoire, peu importe ce que j'essaie. J'ai regardé d'autres questions, y compris une qui liste un fichier de suppression de valgrind pour GTK, mais cela n'a pas changé le résultat.

Voici l'extrait de code le plus simple pour reproduire mon problème :

#include "gtk/gtk.h"

int main()
{
    GtkWidget * widget = gtk_fixed_new();
    g_object_ref(widget);
    g_object_ref_sink(widget); // remove floating reference, and own this object ourselves

    g_object_unref(widget);

    gtk_widget_destroy(widget);
}

Je m'attends à ce que (après avoir traité les références flottantes), la fonction unref() réduise le nombre de références à zéro, puis que toute la mémoire soit libérée. J'ai ajouté la fonction gtk_widget_destroy() pour faire bonne mesure, mais je ne suis pas sûr qu'elle soit vraiment nécessaire (et elle ne change pas l'ampleur de la fuite).

La sortie avec la commande valgrind G_SLICE=debug-blocks valgrind ./t3 --supression=~/Downloads/GNOME.supp de la question Fuites de mémoire dans le programme GTK hello_world est

==10079== HEAP SUMMARY:
==10079==     in use at exit: 164,338 bytes in 847 blocks
==10079==   total heap usage: 1,380 allocs, 533 frees, 219,176 bytes allocated
==10079== 
==10079== LEAK SUMMARY:
==10079==    definitely lost: 0 bytes in 0 blocks
==10079==    indirectly lost: 0 bytes in 0 blocks
==10079==      possibly lost: 21,350 bytes in 174 blocks
==10079==    still reachable: 142,988 bytes in 673 blocks
==10079==         suppressed: 0 bytes in 0 blocks
==10079== Rerun with --leak-check=full to see details of leaked memory

L'autre documentation que j'ai consultée est http://www.demko.ca/blog/posts/200705_gtkmm_refcoutning.txt y https://developer.gnome.org/gtk2/2.24/GtkObject.html

Vous pouvez compiler mon extrait avec

gcc -std=gnu99 `pkg-config --cflags gtk+-2.0` t3.c -o t3 `pkg-config --libs gtk+-2.0 gthread-2.0`

Quelqu'un sait-il ce que j'ai manqué ? Y a-t-il une autre fonction que je devrais appeler pour m'assurer que la mémoire est libérée ?

8voto

ManuelH Points 733
 - g_object_ref

  Increases ref count by one

 - g_object_unref

  Decreases ref count by one, if ref count == 0, the object is destroyed

 - g_object_ref_sink

  IF the object has a floating ref, it converts that reference to a normal ref (sinks it)
  ELSE it increases the ref count by one

 - All objects start with a floating ref count of 1

Pour une lecture plus approfondie, je vous suggère de jeter un coup d'œil à l'article suivant : Introduction à la gestion de la mémoire dans GTK+

Maintenant, pour passer à votre exemple, regardons les appels de fonction et ce qu'ils font :

GtkWidget * widget = gtk_fixed_new(); //widget created with ref count of 1 | floating = true
g_object_ref(widget); // floating = true, ref count increased to 2
g_object_ref_sink(widget); // floating = false, ref count remains at 2

g_object_unref(widget); // floating = false, ref count decreases to 1

//No further unrefs, hello leak!

J'espère que cela explique votre fuite, assurez-vous de lire l'article mentionné ci-dessus.

1voto

golen Points 11

g_object_is_floating est un appel api qui peut être utilisé pour trouver si un objet gtk est compté en référence à virgule flottante ou non. Voici un lien vers un exemple de code : http://wikistack.com/managing-gtk-memorygui-application-interview-question/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X