After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 453663 - Leak when returning a different object in constructor
Leak when returning a different object in constructor
Status: RESOLVED NOTABUG
Product: glib
Classification: Platform
Component: gobject
2.12.x
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2007-07-04 12:21 UTC by Johan (not receiving bugmail) Dahlin
Modified: 2007-07-04 13:29 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
testcase (3.55 KB, patch)
2007-07-04 12:21 UTC, Johan (not receiving bugmail) Dahlin
none Details | Review

Description Johan (not receiving bugmail) Dahlin 2007-07-04 12:21:26 UTC
If you override constructor in your GObject subclass you'll have a small leak if you return a different object in the constructor.

Valgrind reports:

==24536== 162 (140 direct, 22 indirect) bytes in 2 blocks are definitely lost in loss record 55 of 97
==24536==    at 0x4021396: malloc (vg_replace_malloc.c:149)
==24536==    by 0x45F2665: g_malloc (gmem.c:131)
==24536==    by 0x46073AA: g_slice_alloc (gslice.c:803)
==24536==    by 0x45D87C5: g_datalist_id_set_data_full (gdataset.c:292)
==24536==    by 0x4589076: g_object_init (gobjectnotifyqueue.c:77)
==24536==    by 0x45A55AC: g_type_create_instance (gtype.c:1561)
==24536==    by 0x458B811: g_object_constructor (gobject.c:1046)
==24536==    by 0x8048CDF: gtk_builder_custom_constructor (gobject.c:112)
==24536==    by 0x458996A: g_object_newv (gobject.c:937)
==24536==    by 0x458A5E8: g_object_new_valist (gobject.c:1027)
==24536==    by 0x458A6EF: g_object_new (gobject.c:795)
==24536==    by 0x8048D56: main (gobject.c:127)

Changing the constructor to return the constructed object makes the memory leak go away.
Comment 1 Johan (not receiving bugmail) Dahlin 2007-07-04 12:21:57 UTC
Created attachment 91176 [details] [review]
testcase
Comment 2 Tim Janik 2007-07-04 12:35:41 UTC
(In reply to comment #0)
> If you override constructor in your GObject subclass you'll have a small leak
> if you return a different object in the constructor.

well, if you override the constructor to return your own object (usually singleton pattern), you of course must not create a new object:

>static GObject *
>gtk_builder_custom_constructor (GType                  type,
>				guint                  n_construct_properties,
>				GObjectConstructParam *construct_properties)
>{
>  GObject *custom, *obj;
>  
>  custom = G_OBJECT_CLASS (gtk_builder_custom_parent_class)->constructor (type,
>                                n_construct_properties, construct_properties);

heh, what do you think is this chaining up doing here? you're creating a new object and then forget about it. of course that'll leak. simply don't chain up here.

>  obj = G_OBJECT (gtk_label_new ("test"));
>  g_object_unref (custom);

this is not good enough to get rid of a partially constructed (and possibly floating) object. if you chain up above you also have to return the object.

>  return obj;
>}

i.e. use this instead:

static GObject *singleton = NULL; // initialized somewhere

static GObject*
gtk_builder_custom_constructor (GType                  type,
				guint                  n_construct_properties,
				GObjectConstructParam *construct_properties)
{
  return g_object_ref (singleton);
}
Comment 3 Johan (not receiving bugmail) Dahlin 2007-07-04 13:21:23 UTC
(In reply to comment #2)
> (In reply to comment #0)
> > If you override constructor in your GObject subclass you'll have a small leak
> > if you return a different object in the constructor.

That's unfortunate and should be told somewhere, perhaps in the reference manual.

Python allows you to do this by overriding __new__, which is similar to GObject's constructor.

> >static GObject *
> >gtk_builder_custom_constructor (GType                  type,
> >				guint                  n_construct_properties,
> >				GObjectConstructParam *construct_properties)
> >{
> >  GObject *custom, *obj;
> >  
> >  custom = G_OBJECT_CLASS (gtk_builder_custom_parent_class)->constructor (type,
> >                                n_construct_properties, construct_properties);
> 
> heh, what do you think is this chaining up doing here? you're creating a new
> object and then forget about it. of course that'll leak. simply don't chain up
> here.

Because I actually want to access the construct only property that's the only reason I have the object.

> >  obj = G_OBJECT (gtk_label_new ("test"));
> >  g_object_unref (custom);
> 
> this is not good enough to get rid of a partially constructed (and possibly
> floating) object. if you chain up above you also have to return the object.

Assuming this construct is supported, is it possible to get rid of it?

Comment 4 Tim Janik 2007-07-04 13:29:05 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > (In reply to comment #0)
> > >static GObject *
> > >gtk_builder_custom_constructor (GType                  type,
> > >				guint                  n_construct_properties,
> > >				GObjectConstructParam *construct_properties)
> > >{
> > >  GObject *custom, *obj;
> > >  
> > >  custom = G_OBJECT_CLASS (gtk_builder_custom_parent_class)->constructor (type,
> > >                                n_construct_properties, construct_properties);
> > 
> > heh, what do you think is this chaining up doing here? you're creating a new
> > object and then forget about it. of course that'll leak. simply don't chain up
> > here.
> 
> Because I actually want to access the construct only property that's the only
> reason I have the object.

if you have construct-only pproperties you shouldn't be fiddling with the constructor at all. it simply doesn't make sense to create a second singleton with different construct properties.

> > >  obj = G_OBJECT (gtk_label_new ("test"));
> > >  g_object_unref (custom);
> > 
> > this is not good enough to get rid of a partially constructed (and possibly
> > floating) object. if you chain up above you also have to return the object.
> 
> Assuming this construct is supported, is it possible to get rid of it?

i'm not sure what you're asking/assuming. if you mean to ask whether there is a way to not return the chain-constructed object, the answer is no, as stated already. the object is really partially constructed and a lot of the neccessary stuff and cleanups happen after it's returned.