当我运行这个简单的测试程序时,Valgrind报告内存泄漏:
#include <gdk-pixbuf/gdk-pixbuf.h>
int main() {
GdkPixbuf* buf;
GError* err = NULL;
buf = gdk_pixbuf_new_from_file("test.jpg", &err);
g_assert_no_error(err);
g_object_unref(buf);
return 0;
}
我知道关于Valgrind和GLib/GDK/GTK的问题,以及关于这个问题的几个StackOverflow答案(例如这个,这个和其他)。
对于GLib,用G_DEBUG=gc-friendly G_SLICE=always-malloc
作为valgrind
命令的前缀就足够了(尽管我仍然有一些"仍然可到达"的泄漏,如果它们来自GLib,我将忽略它们)。
G_DEBUG=resident-modules
(此处建议)和G_SLICE=debug-blocks
(此处建议),但"可能丢失"的泄漏仍然存在。我还尝试了几个GNOME的抑制,即GDK的一个,但无济于事。
我的问题是:是我唯一的选择来创建一个抑制文件为这种情况下还是有什么问题的代码?
程序是用:
编译的gcc -Wall -std=c99 -g -pedantic `pkg-config --cflags glib-2.0 gdk-pixbuf-2.0` pixbuf.c -o pixbuf `pkg-config --libs glib-2.0 gdk-pixbuf-2.0`
我使用的是GDK-Pixbuf 2.30.7 (Ubuntu 14.04)。
我看到的所有"可能丢失的"块都是在向GObject注册类型时出现的。这些确实仍然可以到达,只是valgrind不知道如何到达它们(诚然,这有点奇怪,我不怪valgrind感到困惑),所以它报告它们为"可能丢失"而不是"仍然可以到达"。
你的代码没有任何问题,在glib中也没有真正的泄漏。你应该使用一个抑制文件
如果gdk_pixbuf_new_from_file()由于某种原因失败(例如,文件不存在),"buf"将被赋值为NULL,错误将通过"err"返回。然后g_assert_no_error(err)将终止程序,但它不会释放"err"所指向的内存。如果您自己管理错误并使用g_free_error(err)释放"err",情况会更好。在调用"gdk_pixbuf_new_from_file"之后,删除剩下的代码,用以下代码替换它,看看你从Valgrind得到的结果:
if (!buf) {
g_printerr("%sn", err->message);
g_free_error(err);
}
else {
g_object_unref(buf);
}
顺便说一下,我不是很熟悉Valgrind,我只是指出可能的内存泄漏。尽管在那个时候你的程序可能已经终止了,内核可能足够聪明地回收它分配给程序的内存块。