Re: Can I use gtk_widget_unref() to releasetthe object created by gtk_invisible_new()?
- Date: Wed, 30 Jan 2008 15:28:00 +0800
- From: Brian.Lu@xxxxxxx
- Subject: 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@xxxxxxxxx
>>>> http://mail.gnome.org/mailman/listinfo/gtk-devel-list
>>>>
>>>>
>>>
>>>
>> _______________________________________________
>> gtk-devel-list mailing list
>> gtk-devel-list@xxxxxxxxx
>> http://mail.gnome.org/mailman/listinfo/gtk-devel-list
>>
>
>
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@xxxxxxxxx
http://mail.gnome.org/mailman/listinfo/gtk-devel-list