[Interest] Double destruction of Qt objects in Qt example code?

K. Frank kfrank29.c at gmail.com
Sat Aug 18 19:46:26 CEST 2012


Hi Nikos!

Thanks for your comments.  I do have a follow-up question (below).

On Sat, Aug 18, 2012 at 1:05 PM, Nikos Chantziaras <realnc at gmail.com> wrote:
> On 18/08/12 19:38, K. Frank wrote:
>> Hello List!
>>
>> I see the following code snippet in some Qt documentation:
>>
>>     QGraphicsScene scene;
>>     scene.addText("Hello, world!");
>>
>>     QGraphicsView view(&scene);
>>     view.show();
>>
>> (From http://doc.qt.nokia.com/4.7-snapshot/qgraphicsview.html)
>>
>> Both scene and view are automatic variables.  If this example were
>> taken literally, would it lead to a double-destruction bug?
>>
>> As an automatic variable, view is destroyed when it goes out of
>> scope.  Then scene goes out of scope and is destroyed.  I imagine
>> that scene is the parent of view in the usual Qt sense, so that
>> scene's destructor deletes view, which would be a bug.
>
> When 'view' is destroyed (because it goes out of scope), it tells
> 'scene' about it.  So scene removes it from its list of children.  A
> double delete is thus avoided.
>
> This is possible because C++ guarantees that automatic vars are
> destroyed in the reverse order of their declaration; 'view' will always
> be destroyed before 'scene', and thus its dtor will always be able to
> communicate to 'scene' that its being destroyed.
>
> PS:
> I just googled this in order to find something to support the above
> statement.  And what I found is actually written in the Qt docs :-)
>
> http://doc-snapshot.qt-project.org/4.8/objecttrees.html#construction-destruction-order-of-qobjects

Thank you for this link -- it makes quite clear what is going on.

Just to recapitulate and confirm what you and Sean (and the link) said:

The Qt parent-child-ownership-destruction mechanism works as
follows:  When a parent is destroyed, it automatically calls its
children's destructors.  When a child is destroyed, it automatically
"deregisters" itself from its parent, so that it is no longer a child.

So you can explicitly destroy a child (delete it or have it go out of
scope) before its parent is destroyed, but not after.

This does raise one c++ / Qt question for me:  When an automatic
variable goes out of scope, its destructor is called (and, at some
point, the stack is popped, but not by the destructor nor by any
explicit user code).  When a heap variable is deleted, its destructor
is called, and the equivalent of free is called.  The point is delete
is not called (in correct code) on automatic variables.

How can the Qt parent-child system work with both automatic and
heap variables as children?  When a child object registers itself
with its parent (e.g., by being passed a pointer to its parent in its
constructor), neither the child object nor the parent knows whether
the child is an automatic or heap variable (and, using portable
standard c++, can't know).  So how can the parent know (when the
parent is destroyed) whether to call the child's destructor directly or
to call delete on the child?

To be concrete, I imagine that when a parent is destroyed, it does
something like this:

   for (QObject *c : children)  delete c;

but if one of the children were a (pointer to a) variable on the stack,
then calling delete on it would be a bug.  (And if the parent didn't
call delete, then it would be a memory leak for children that were
on the heap.)

Any further insight would be appreciated.


K. Frank



More information about the Interest mailing list