SIP - Error in mapped type

Marian Thomsen at
Fri Apr 23 08:04:29 BST 2021


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


(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 *>
#include <vector>

    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.
            return NULL;

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

    // Return the Python list.
    return l;

    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;
        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);


            // 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.

        sipReleaseType(t, kpTypeDef, state);

    // Return the instance on the heap.
    *sipCppPtr = v;

    // Apply the normal transfer.
    return sipGetState(sipTransferObj);

Thank you!



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the PyQt mailing list