Re: Can I use gtk_widget_unref() to releasetthe object created by gtk_invisible_new()?



Hi, Markku,

Thanks a lot for your help.

I did some further investigation on this issue. I have two questions on this issue:

1. The object created by gtk_invisible_new() is not "floating".
Here is a snippet from gtk+-2.12.5/tests/testselection.c

init_atoms();
 selection_widget = gtk_invisible_new ();
*  m = GTK_OBJECT_FLOATING(selection_widget);  //***
 dialog = gtk_dialog_new ();
 gtk_widget_set_name (dialog, "Test Input");

The black line (marked with "**") is added by me.
When I run testselection, "m" is set to 0 instead of 1. Which means the selection_widget is not "floating".
right or I used a wrong macro?

2. How to release an object created by gtk_invisible_new()?
Look at following snippets:

  void InitWidget() {
       mWidget = gtk_invisible_new();
       *gtk_object_ref(GTK_OBJECT(mWidget)); //***
       gtk_object_sink(GTK_OBJECT(mWidget));
       gtk_widget_ensure_style(mWidget);
       mStyle = gtk_widget_get_style(mWidget);
   }

  nsLookAndFeel::~nsLookAndFeel()
  {
      //  gtk_widget_destroy(mWidget);
      gtk_widget_unref(mWidget);
  }

If I comment out the black line (marked with "**"), the mWidget reference count is 1 as expected, but when unref it in nsLookAndFeel::~nsLookAndFeel, thunderbird will crash. It looks like that I can't us gtk_widget_unref() on the object returned by gkt_invisible_new().

So my question is how to "free" an object returned by gtk_invisible_new()?

Thanks a lot

Brian


Markku Vire wrote:
Hi,

The reference that is returned by gtk_invisible_new is not owned by the
caller. If one tries to unref it, it's an immediate memory corruption.

When a toplevel widget is concerned, the things go like the following:
 * New floating GtkWidget is created (not owned by anyone).
 * GTK library takes ownership of the toplevel (calling
   g_object_ref_sink). Floating reference is converted to normal one.
 * Widget pointer is returned (refcount = 1, owner = gtk).

So, in the code you attached gtk_object_ref increases the reference
count to 2, gtk_object_sink does nothing (since it not floating any
more).

Later gtk_widget_unref decreases refcount back to 1, but there is still
one reference left (owned by gtk). Trying to remove it by g_object_unref
is a bug (as you noticed). The way to ask GTK to release the last
reference is to call gtk_widget_destroy.

If you are just interested about the GtkStyle object, you could try
using gtk_rc_get_style_by_paths for example?
Cheers,

-Markku-

On Fri, 2008-01-11 at 16:53 +0800, Brian Lu wrote:
Thanks a lot for your explanation. But look at following snippet from firefox latest code base:
    void InitWidget() {
        mWidget = gtk_invisible_new();
        gtk_object_ref(GTK_OBJECT(mWidget));
        gtk_object_sink(GTK_OBJECT(mWidget));
        gtk_widget_ensure_style(mWidget);
        mStyle = gtk_widget_get_style(mWidget);
    }
see http://lxr.mozilla.org/seamonkey/source/widget/src/gtk2/nsLookAndFeel.h#77
and
nsLookAndFeel::~nsLookAndFeel()
{
    //  gtk_widget_destroy(mWidget);
    gtk_widget_unref(mWidget);
}
see http://lxr.mozilla.org/seamonkey/source/widget/src/gtk2/nsLookAndFeel.cpp#78

I find mWidget is leaked (detected by using libumem.so provided by solaris).

I don't understand why calling gtk_object_ref() to increase mWidget reference count. This causes mWidget's reference count to be 2 and gtk_widget_unref() in deconstructor decreases it to 1.

Thanks

Brian



Markku Vire wrote:
Hi,

The caller doesn't own the returned reference in case of any gtk_*_new
functions, but the results are floating references (they are removed
once somebody calls gtk_object_sink). This is different from normal
GObjects. So, unreffing the returned value causes practically a double
free.

gtk_widget_destroy in turn runs dispose, ie. asks widget to drop
references to other widgets. Dropping external references usually causes
somebody else to drop the last reference to your widget, so it
efectively gets destroyed. In case of toplevels some global window list
is holding the reference.

Calling gtk_widget_destroy without taking ownership a a widget is
usually a bug that causes a memory leak, but this is not the case here,
since we are talking about a toplevel.

Cheers,

-Markku-
On Wed, 2008-01-09 at 17:39 +0800, Brian Lu wrote:
Hi, experts,

I found following codes will crash in gnome 2.21 environment:

  ...
  GtkWidget *foo = gtk_invisible_new();
  gtk_widget_unref(foo);
  ...

But it works well if gtk_widget_unref() is replaced with gtk_widget_destroy().

Does that mean that we can't use gtk_widget_unref() on such object and we can only
use gtk_widget_destroy() to release it?

Thanks

Brian
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]