GNOME Bugzilla – Bug 453663
Leak when returning a different object in constructor
Last modified: 2007-07-04 13:29:05 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.
Created attachment 91176 [details] [review] testcase
(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); }
(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?
(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.