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



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]