SIP - Error in mapped type
Marian Thomsen
marian.th at outlook.de
Fri Apr 23 08:04:29 BST 2021
Hello,
the following mapped type caused the error "free(): double free detected in tcache 2" which I cannot find. Can someone tell me what I'm missing?
PathPoint is a wrapped struct containing some other wrapped structs. The content can also only be an unsigned int and the error is still there.
When I set
gc.set_debug(gc.DEBUG_LEAK)
(meaning postponed garbage collection) in the python script that uses this wrapped vector, the error does not appear.
My guess is that it has something to do with "PathPoint *t" or the ownership of "item" in ConvertToTypeCode.
%MappedType std::vector<PathPoint *>
{
%TypeHeaderCode
#include <vector>
%End
%ConvertFromTypeCode
PyObject *l;
const sipTypeDef* kpTypeDef = sipFindType("PathPoint");
if (!kpTypeDef) {
return NULL;
}
// Create the Python list of the correct length.
if ((l = PyList_New(sipCpp->size())) == NULL) {
return NULL;
}
int i = 0;
// Go through each element in the C++ instance and convert it to the corresponding Python object.
for(std::vector<PathPoint *>::iterator iter = sipCpp->begin(); iter != sipCpp->end(); iter++) {
PathPoint *t = *iter;
PyObject *tobj;
// Get the Python wrapper for the Type instance, creating a new
// one if necessary, and handle any ownership transfer.
if ((tobj = sipConvertFromType(t, kpTypeDef, sipTransferObj)) == NULL) {
// There was an error so garbage collect the Python list.
Py_XDECREF(l);
return NULL;
}
// Add the wrapper to the list.
PyList_SET_ITEM(l, i++, tobj);
}
// Return the Python list.
return l;
%End
%ConvertToTypeCode
const sipTypeDef* kpTypeDef = sipFindType("PathPoint");
if (!kpTypeDef) {
return 0;
}
// See if we are just being asked to check the type of the Python object.
if (sipIsErr == NULL) {
// Check it is a list.
if (!PyList_Check(sipPy)) {
return 0;
}
// Now check each element of the list is of the type we expect.
// The template is for a pointer type so we don't disallow None.
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(sipPy); ++i) {
PyObject *item = PyList_GET_ITEM(sipPy, i);
if (!sipCanConvertToType(item, kpTypeDef, SIP_NOT_NONE)) {
*sipIsErr = 1;
break;
}
}
return 1;
}
// Create the instance on the heap.
std::vector<PathPoint *> *v = new std::vector<PathPoint *>();
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(sipPy); ++i) {
int state;
// Use the SIP API to convert the Python object to the
// corresponding C++ instance. Note that we apply any ownership
// transfer to the list itself, not the individual elements.
PyObject *item = PyList_GET_ITEM(sipPy, i);
PathPoint *t = static_cast<PathPoint*>(sipConvertToType(item, kpTypeDef, sipTransferObj,
SIP_NOT_NONE, &state, sipIsErr));
if (*sipIsErr) {
sipReleaseType(t, kpTypeDef, state);
Py_DECREF(item);
// Tidy up.
delete v;
// There is nothing on the heap.
return 0;
}
// ownership to cpp (no Py_DECREF needed)
sipTransferTo(item, item);
// Add the pointer to the C++ instance.
v->push_back(t);
sipReleaseType(t, kpTypeDef, state);
}
// Return the instance on the heap.
*sipCppPtr = v;
// Apply the normal transfer.
return sipGetState(sipTransferObj);
%End
};
Thank you!
Regards
M.T.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20210423/12fa9db4/attachment-0001.htm>
More information about the PyQt
mailing list