6

たとえば、多くのウィジェットを作成および破棄する必要がある場合など、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() をそこに投げましたが、実際に必要かどうかはわかりません (そして、リークの大きさは変わりません)。

G_SLICE=debug-blocks valgrind ./t3 --supression=~/Downloads/GNOME.supp質問Memory Leaks in GTK hello_world programからの valgrind コマンドの出力は次のとおり です。

==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.txthttps://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`

私が欠けているものを知っている人はいますか?メモリが確実に解放されるようにするために呼び出す必要がある別の関数はありますか?

4

2 に答える 2

8
 - 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!

上記の記事を必ずお読みください。

于 2013-07-18T21:45:11.300 に答える