我试着写第一个GTK +程序。汇编很顺利,但valgrind说存在内存泄漏。我找不到那些人,所以有人可以说我做错了什么?或者是否可以编写没有内存泄漏的图形化Linux程序?
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Hello World");
gtk_container_set_border_width(GTK_CONTAINER(window), 60);
GtkWidget* label = gtk_label_new("Hello, world!");
gtk_container_add(GTK_CONTAINER(window), label);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
gcc -Wall gtkhello.c -o gtkhello $(pkg-config --cflags --libs gtk+-2.0)
valgrind -v ./gtkhello
...
==9395== HEAP SUMMARY:
==9395== in use at exit: 538,930 bytes in 6,547 blocks
==9395== total heap usage: 21,434 allocs, 14,887 frees, 2,964,543 bytes allocated
==9395==
==9395== Searching for pointers to 6,547 not-freed blocks
==9395== Checked 949,656 bytes
==9395==
==9395== LEAK SUMMARY:
==9395== definitely lost: 4,480 bytes in 30 blocks
==9395== indirectly lost: 5,160 bytes in 256 blocks
==9395== possibly lost: 180,879 bytes in 1,716 blocks
==9395== still reachable: 348,411 bytes in 4,545 blocks
==9395== suppressed: 0 bytes in 0 blocks
==9395== Rerun with --leak-check=full to see details of leaked memory
==9395==
==9395== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==9395== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
答案 0 :(得分:1)
你没有做错任何事。 GTK小部件使用引用计数,但在您的程序中所有引用都被处理,因此您不会(手动)泄漏任何内容。
那么为什么Valgrind声称你是谁?
首先,GLib有自己的“slab”内存分配器,称为GSlice
,对于小分配,它通常比系统malloc
更快。不幸的是,它让Valgrind感到困惑,但是如果你设置环境变量G_SLICE=always-malloc
,GSlice
就会被有效关闭。
其次,你可以设置G_DEBUG=gc-friendly
,这可以帮助Valgrind产生更准确的结果(虽然我的经验一般没有任何区别)。
这两个环境变量都列在GLib documentation。
中不幸的是,即使您同时执行这两项操作,Valgrind仍会报告您的应用程序泄漏了内存。原因是GTK(及其底层库)在启动时分配了一些“静态”内存,在程序退出之前不会被释放。这不是一个真正的问题,因为通常程序会在gtk_main()
返回后立即结束,然后操作系统会释放所有剩余资源,因此您不会真正泄漏任何内容。 Valgrind认为你是,但由于这个原因,拥有gtk_deinit()
函数会很好,但遗憾的是没有。{/ p>
你能做的最好的事情就是通过一个抑制文件来教导Valgrind忽略这些事情。 Valgrind page on the Gnome Wiki详细介绍了所有这些以及更多内容。