Search code examples
pythonpython-c-api

How python interpreter handle negative reference count of object?


Will python interpreter deallocate memory of object if its reference count is negative?

For example if I have a such code will time_tuple be deallocated by python?

PyObject* list = PyList_New(2);
PyObject *time_tuple = Py_BuildValue("(s, s)", "Time", "O");
PyList_SetItem(list, 0, time_tuple);
Py_XDECREF(time_tuple);
Py_XDECREF(list);

Please refer to some documentation in your answer if you can.


Solution

  • The interpreter should never encounter a negative reference count. If the reference count reaches zero, it means that there are zero references to that object. The object will be deallocated as soon as this happens.

    To quote the Python documentation:

    If the reference count reaches zero, the object’s type’s deallocation function (which must not be NULL) is invoked.

    See also here for more.

    It is also important to note that in Python, in addition to the reference count, it is important to keep track of who actually owns those references.

    In the example you provided:

    1. Py_BuildValue() returns a new reference which is then owned by you and held in time_tuple. At this point the tuple has a reference count of 1.

    2. PyList_SetItem() steals the ownership reference, the tuple still has a reference count of 1, but the reference is owned by list.

    3. Py_XDECREF(time_tuple) decrements the reference count of the tuple to 0 and the object is deallocated. This is an error, as the reference is owned by list.

    4. Py_XDECREF(list) decrements the reference count of the list to 0 and the list is deallocated. The reference to the tuple is owned by the list, so it decrements its reference count.

    5. Unfortunately, the tuple has already been allocated and your program crashes. Or worse, it could go on running for a while, crashing in an unrelated part of the code. Debugging this is usually loads of fun.