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 >> > > _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list