【问题标题】:Properly deallocating a GtkBuilder Object正确释放 GtkBuilder 对象
【发布时间】:2018-02-21 17:17:19
【问题描述】:

我有以下 GTK+ 程序

////////////////////////////////////////////////////
// Example can be compiled with:
// gcc gui.c `pkg-config --cflags --libs gtk+-2.0`
//
// GUI file from glade must be in same folder from
// which the compiled binary is called.
////////////////////////////////////////////////////

#include <gtk/gtk.h>

int main(int argc, char *argv[]) {
    GtkBuilder *gtkBuilder = gtk_builder_new();

    gtk_init(&argc, &argv);

    gtk_builder_add_from_file(gtkBuilder, "../gui.glade", NULL);

    gtk_builder_connect_signals(gtkBuilder, NULL);

    gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "main")));

    g_object_unref(G_OBJECT(gtkBuilder));

//  g_free(gtkBuilder);

    gtk_main();

    return 0;
}

以及对应的 XML Glade 文件:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.24"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkWindow" id="main">
    <property name="width_request">400</property>
    <property name="height_request">300</property>
    <property name="can_focus">False</property>
    <property name="default_width">690</property>
    <property name="default_height">500</property>
    <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>

当我编译并使用 Valgrind 运行内存检查时,它抱怨为 GtkBuilder 分配的内存可能丢失了。当我取消注释 g_free() 指令时,我收到有关对 free() 的无效调用的错误。

我知道 GTK+ 框架本身存在一些漏洞,即它不会在其整个生命周期内释放所需的资源。 GtkBuilder 是那些将被“泄露”的资源之一,还是有办法在 Valgrind 不抱怨的情况下正确释放它?

【问题讨论】:

  • 您需要 G_DEBUG=gc-friendlyG_SLICE=always-malloc 才能使 valgrind 与 GObject 正常工作。 This answer also has some useful information.
  • 拜托拜托,除非你真的有很好的理由这样做(比如维护一个不值得迁移的大而老的应用程序),否则不要使用 GTK+ 2。GTK+ 3 已经存在 7 年了年 (!),GTK+ 4 可能会在 2019 年发布。
  • @liberforce 我可能会将程序迁移到 GTK+ 3。我开始使用 GTK+2 的原因仅仅是因为 Slackware 为 Glade 提供了一个支持 GTK+2 的版本。
  • 在发行版中,glade 通常打包为gladeglade3,一个版本用于GTK+ 2,另一个用于GTK+ 3。棘手的是glade3 用于GTK+ 2 (版本 glade 用于 GTK+ 3(版本 > 3.8),如glade website 所示。所以你应该可以找到glade for slackware

标签: c memory-leaks gtk valgrind gtk2


【解决方案1】:

在“取消引用”之后,由于您没有增加引用计数,即引用计数已降至 0,因此该对象被释放。之后使用g_free() 会出错。

来自documentation

g_object_unref ()

void g_object_unref (gpointer object);

减少 object 的引用计数。 当它的引用计数 下降到 0,对象被最终确定(即它的内存被释放)。

如果指向GObject 的指针将来可能会被重用(例如,如果 它是另一个对象的实例变量),建议 清除指向NULL 的指针,而不是保留指向 可能无效的GObject 实例。为此使用g_clear_object ()

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 2013-03-21
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多