How to correctly (and effectively) release memory

2019-06-22 13:43发布

I'm trying to understand how to correctly release memory when I am finished with a GTK widget, for example if I need to create and destroy many widgets. However, valgrind seems to indicate a memory leak regardless of what I try. I've looked at other questions, including one that lists a valgrind supression file for GTK, but it didn't change the result.

Here's the simplest code snippet to reproduce my issue:

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

My expectation is that (after dealing with floating references), the unref() function should reduce the reference count to zero, and then all memory is released. I threw the gtk_widget_destroy() in there for good measure, but I'm not sure it should actually be necessary (and it doesn't change the magnitude of the leak).

The output with the valgrind command G_SLICE=debug-blocks valgrind ./t3 --supression=~/Downloads/GNOME.supp from question Memory Leaks in GTK hello_world program is

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

The other documentation I've looked at is http://www.demko.ca/blog/posts/200705_gtkmm_refcoutning.txt and https://developer.gnome.org/gtk2/2.24/GtkObject.html

You can compile my snippet with

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

Anyone know what I'm missing? Is there another function I should be calling to ensure the memory is released?

2条回答
我只想做你的唯一
2楼-- · 2019-06-22 14:11
 - 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

For some further reading, I would suggest you take a look at the following article: Introduction to Memory Management in GTK+

Now, moving on to your example, lets look at the function calls and what they do:

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!

I hope that explains your leak, be sure to read the article mentioned above.

查看更多
Animai°情兽
3楼-- · 2019-06-22 14:16

g_object_is_floating is an api call which can be used to find if gtk object is floating point reference counted or not. Here is a link to example code: http://wikistack.com/managing-gtk-memorygui-application-interview-question/

查看更多
登录 后发表回答