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