Question

We have some code which creates a python list and then appends data items to it. Our concern is that if one of the data items turns out to be NULL, then we consider the whole of the list (that is, any previously added items) to be worthless, and we'd like to free the list and it's memory. What do I need to do to ensure that the garbage collector frees up all the memory?

The current code is:

PyObject* retval = PyList_New(0);

QList<QVariant> varList = value.toList();
foreach(QVariant var, varList)
{
    // variantToPython(var) returns either NULL
    // or a valid object whose reference count is 1
    PyObject *pyVar = variantToPython(var);
    if (pyVar)
    {
        PyList_Append(retval, pyVar);
        Py_DECREF(pyVar);
    }
}

return retval;

but we'd like to do something like this:

PyObject* retval = PyList_New(0);

QList<QVariant> varList = value.toList();
foreach(QVariant var, varList)
{
    // variantToPython(var) returns either NULL
    // or a valid object whose reference count is 1
    PyObject *pyVar = variantToPython(var);
    if (pyVar)
    {
        PyList_Append(retval, pyVar);
        Py_DECREF(pyVar);
    }
    else
    {
        Py_DECREF(retval);
        retval = 0;
        break;
    }
}

return retval;

so is the DECREF on the list object adequate to ensure the GC frees everything?

Was it helpful?

Solution

Yes, since PyList_New() creates an object with a refcount of 1. You should set an appropriate exception before returning though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top