[PyKDE] Re: Memory leak & segfault with deleteLater
Phil Thompson
phil at riverbankcomputing.co.uk
Mon Jun 20 21:22:14 BST 2005
On Monday 20 June 2005 4:15 pm, Giovanni Bajo wrote:
> Hello,
>
> two problems, which are very similar (and maybe related). The first is a
>
> segmentation fault:
> >>> from qt import *
> >>> app = QApplication([])
> >>> w1 = QWidget(None)
w1 reference count is 1.
> >>> w2 = QWidget(w1)
w2 reference count is 2. This is because ownership of w2 is with C++ because
it has a parent. The extra reference is needed to make sure valuable data
isn't lost if the application doesn't keep a reference to the child.
> >>> w2.xxxx = w1
w1 reference count is 2.
> >>> w2.deleteLater()
A DeferredDelete event is posted to w2.
> >>> del w1
w1 reference count is 1.
> >>> del w2
w2 reference count is 1.
> >>> app.processEvents()
w2 handles the DeferredDelete event and calls it's own virtual dtor. This is
"caught" by the dtor of an internally generated QWidget sub-class which
removes w2's extra reference. w2 reference count is now 0.
Python now garbage collects w2, part of which is to reduce the reference count
of w1 to 0. As w1 is owned by Python (because the C++ instance doesn't have a
parent) it calls the C++ dtor. This then calls the C++ dtor of it's children
(ie. w2) - but we are already in w2's dtor. The problem is that we haven't
yet executed the base QObject dtor which removes an instance from it's parent
and would prevent the recursive dtor call.
> Segmentation fault
>
> The thing I don't understand is why it does not crash if you don't add a
> reference to w1 from inside w2.
w1 will be garbage collected by "del w1". This will cause the C++ dtors for w2
and w1 to execute. The w2 dtor will remove the extra reference to w2 (leaving
it at 1).
"del w2" will then cause w2 to be garbage collected. Nothing extra happens
here because PyQt knows that the wrapped C++ instance has already gone.
I'm not sure if anything can be done to detect and/or prevent the problem. It
would be easy enough to contrive the same problem in C++, so I don't really
see it as a PyQt problem. I'm open to suggestions.
> The second problem is a memory leak:
I'll think about this tomorrow - my head hurts at the moment.
Phil
More information about the PyQt
mailing list