Can`t unref in a simple program with leaks

In the program below I can not do g_object_unref(label) after gtk_container_add().
According to the documentation, after calling gtk_container_add function, a second link to the label is created. To free memory after the wnd is destroyed, I should to reduce the ref-count of label to 1. Otherwise there will be leaks.

#include <gtk/gtk.h>

int main() {
    gtk_init(NULL, NULL);

    GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *label = gtk_label_new("text");
    
    gtk_container_add(GTK_CONTAINER(wnd), label);
    g_object_unref(label);

    g_signal_connect(wnd, "destroy", gtk_main_quit, NULL);
    gtk_widget_show_all(wnd);

    gtk_main();
}

But in this case i have this problem:

label finalizes before the end of the program, as if the ref was equal to 1.

If I remove g_object_unref (label), then the Valgrind will detect a leaks in 2 blocks on 768 bytes:

`==18815== LEAK SUMMARY:
==18815==    definitely lost: 768 bytes in 2 blocks
==18815==    indirectly lost: 8,144 bytes in 347 blocks
==18815==      possibly lost: 4,932 bytes in 54 blocks
==18815==    still reachable: 2,294,825 bytes in 25,938 blocks
==18815==                       of which reachable via heuristic:
==18815==                         length64           : 5,840 bytes in 95 blocks
==18815==                         newarray           : 2,144 bytes in 54 blocks
==18815==         suppressed: 768 bytes in 1 blocks
==18815== Rerun with --leak-check=full to see details of leaked memory
==18815== 
==18815== For lists of detected and suppressed errors, rerun with: -s
==18815== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)`

I start program with this suppression gtk.supp like this:
valgrind --leak-check=summary --show-possibly-lost=no --suppressions=../../Downloads/gtk.supp ./a.out

You must not release the reference after adding a widget to a container.

Widgets have an initially floating reference (they inherit from GInitiallyUnowned), which gets removed, or “sunk”, once acquire a parent.

The parent is responsible for destroying its children (recursively) and release their references.

You will need to use the glib.supp file provided by GLib alongside the gtk.supp file—though be warned that the GTK suppression file is still incomplete, and won’t help much with one-off allocations coming from GTK’s own dependencies.

Ok, Thank you. Than another question:
When I call gtk_show_all(wnd) like this i will have the same leaks:

    gtk_init(NULL, NULL);

    GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *label = gtk_label_new("text");

    gtk_container_add(GTK_CONTAINER(wnd), label);

    gtk_widget_show_all(wnd);

    gtk_widget_destroy(wnd);

But in such an implementation i will not have leaks:

gtk_widget_show(wnd);
gtk_widget_show(label);

You have carefully avoided pasting the “leaks”, so I can’t really answer any question in depth.

All I can say is that gtk_widget_show_all() is a recursive call to gtk_widget_show(), so it doesn’t really leak—and if it did leak, it would have been fixed already, given how common the call is.

Thanks for the detailed answers. So, is there any way to correctly monitor leaks using valgrind or in another way, that would not show false-positive results? Suppressions do not give the desired result.

You typically need to learn how to read the output of Valgrind; the summary at the end is just that: a summary. You need to go through every entry and understand where it’s coming from, just like reading a backtrace from GDB in order to understand where a crash is happening.

They do work, but they assume that they are kept up to date, and cover all the dependencies.

Ok, Thank a lot. Have a nice day.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.