[PyQt] struct or class members in a class - accessing free memory.
Phil Thompson
phil at riverbankcomputing.com
Fri Jul 16 19:18:51 BST 2010
On Fri, 16 Jul 2010 11:02:22 -0600, Brian Olson <brian at amergint.com>
wrote:
> Sorry if this actually made it through the first time, I've looked on
the
> archives and don't see it. I've joined the mailing list now, so maybe
> that's a necessary prerequisite for posting.
>
> Begin forwarded message:
>
>>
>> I've been using SIP successfully for over a year, and it's a great
>> product!
>>
>> I'm upgrading from 4.7.9 to 4.10.3 (well .4 now) and ran into a problem
>> I had to work around and wanted to see if it's actually a bug.
>>
>> I have a class like this:
>>
>> class OuterClass
>> {
>> public:
>> struct Inner
>> {
>> int x;
>> };
>>
>> OuterClass()
>> ~OuterClass()
>> Inner inner;
>> };
>>
>> With the default SIP wrapper, I can do this:
>>
>> o = OuterClass()
>> i = o.inner
>> del o # actually causes the delete of outer (and inner)!
>> print i.x # accesses deleted cpp object
>>
>> I was able to fix it by taking advantage of the ->user member, but I'll
>> have to do this for every struct/class that is a member variable in a
>> class.
>>
>> class OuterClass
>> {
>> %TypeHeaderCode
>> #include "tester.h"
>> %End
>> public:
>> struct Inner
>> {
>> int x;
>> };
>> OuterClass();
>> ~OuterClass();
>> Inner inner;
>> %GetCode
>> sipPy = sipConvertFromType(&sipCpp->inner,sipType_OuterClass_Inner,
>> NULL);
>>
>> // if user is not null, we got an already created sipPy with the
>> // user pointer already set to the containing class
>> if (((sipSimpleWrapper *)sipPy)->user == NULL)
>> {
>> PyObject *outerPy =
>> sipConvertFromType(sipCpp,sipType_OuterClass, NULL);
>> ((sipSimpleWrapper *)sipPy)->user = outerPy;
>> }
>> %End
>> };
>>
>> This takes advantage of the fact that getting the OuterClass python
>> object increments the refcount on it, and that deallocing the inner
class
>> automatically decrefs the user python object. It works even if you grab
>> multiple references to the inner member variable and deletes outer when
>> the last inner reference is deleted.
>>
>> It might make more sense to fix it by using the extra_refs, but it
>> wasn't as accessible from the sip file.
>>
>> Let me know what you think.
>>
>> Enclosed is the test code. You can see the problem if you comment out
>> the %GetCode section.
It's certainly not a bug, but the suggestion is interesting. I'll think
about it for a future version.
Phil
More information about the PyQt
mailing list