[PyQt] SIP: memory leak in mapped type?

Giovanni Bajo rasky at develer.com
Tue Jul 24 15:45:47 BST 2007


this is some mapped code I have written:

%MappedType std::vector<TYPE>
#include <vector>

     PyObject *l;

     // Create the Python list of the correct length.
     if ((l = PyList_New(sipCpp -> size())) == NULL)
         return NULL;

     // Go through each element in the C++ instance and convert it to a
     // wrapped P2d.
     for (int i = 0; i < (int)sipCpp -> size(); ++i)
         TYPE *cpp = new TYPE(sipCpp -> at(i));
         PyObject *pobj;

         // Get the Python wrapper for the Type instance, creating a new
         // one if necessary, and handle any ownership transfer.
         if ((pobj = sipConvertFromInstance(cpp, sipClass_TYPE, 
sipTransferObj)) == NULL)
             // There was an error so garbage collect the Python list.
             return NULL;

         // Add the wrapper to the list.
         PyList_SET_ITEM(l, i, pobj);

     // Return the Python list.
     return l;

It's part of a stl.sip I have posted in full some months ago, and it's 
very similar to the sample code in the SIP documentation. Now, I found 
out that this code causes memory leaks, which can be fixed with this 
simple patch:

-        if ((pobj = sipConvertFromInstance(cpp, sipClass_TYPE, 
sipTransferObj)) == NULL)
+        if ((pobj = sipConvertFromInstance(cpp, sipClass_TYPE, 
Py_None)) == NULL)

But then, I was wondering about the semantic of sipTransferObj. The 
documentation isn't very clear about its usage. In fact, it's not clear 
in this case whether it should apply to the whole vectors or to the 
individual objects in the vector.

Does the fix make sense? And if so, why it isn't required in the SIP 
documentation example? And finally, with the above patch, the value of 
sipTransferObj is totally ignored by the code: how can that be right?

Giovanni Bajo

More information about the PyQt mailing list