[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