如何正确(和有效)释放gtk小部件中的内存

我正在尝试了解如何在完成GTK小部件时正确释放内存,例如,如果我需要创建和销毁许多小部件。 但是,无论我尝试什么,valgrind似乎都表明内存泄漏。 我已经查看了其他问题,包括列出GTK的valgrind抑制文件的问题,但它没有改变结果。

这是重现我的问题的最简单的代码片段:

#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); } 

我的期望是(在处理浮动引用之后),unref()函数应该将引用计数减少到零,然后释放所有内存。 我把gtk_widget_destroy()放在那里以获得良好的衡量标准,但我不确定它实际上是否必要(并且它不会改变泄漏的大小)。

使用valgrind命令输出G_SLICE=debug-blocks valgrind ./t3 --supression=~/Downloads/GNOME.supp来自GTK hello_world程序中的Memory Leaks问题是

 ==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 

我看过的其他文档是http://www.demko.ca/blog/posts/200705_gtkmm_refcoutning.txt和https://developer.gnome.org/gtk2/2.24/GtkObject.html

你可以编译我的代码片段

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

谁知道我错过了什么? 我应该调用另一个函数来确保释放内存吗?

  - 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 

对于进一步的阅读,我建议你看看下面的文章: GTK +中的内存管理简介

现在,继续您的示例,让我们看看函数调用及其执行的操作:

 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! 

我希望能解释你的泄漏,一定要阅读上面提到的文章。

g_object_is_floating是一个api调用,可用于查找gtk对象是否为浮点引用计数。 以下是示例代码的链接: http : //wikistack.com/managing-gtk-memorygui-application-interview-question/