[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