3

What is the proper way to free a PyTuple object using the Python C-API?

I know that tuples are somewhat special when it comes to the reference counting semantics, since PyTuple_SetItem "steals" the reference to the inserted element. I also know that decrementing the reference of a tuple object decrements the reference count of all the elements in the tuple.

With this in mind, I would think it should be safe to say:

#include <Python.h>
#include <stdio.h>

int main()
{
    PyObject* tup = PyTuple_New(1);
    PyTuple_SetItem(tup, 0, PyLong_FromLong(100L));

    printf("Ref Count: %d\n", tup->ob_refcnt);
    Py_DECREF(tup);
}

But the last line causes a Segmentation Fault, when I decrement the tuple reference count. I don't understand why this happens. Right before the call to Py_DECREF the reference count is 1, so what's the issue here?

Channel72
  • 24,139
  • 32
  • 108
  • 180
  • The Py_DECREF will free the tuple but a Segmentation Fault at that point probably indicates that you have already corrupted memory in some earlier code. Look elsewhere in your code. If you can post a complete runnable sample that demonstrates the problem (probably not easy I know). – Duncan Feb 04 '11 at 13:34
  • No, that is literally the entire program. However, I added in the surrounding `#include` statements and `main` function if that helps. – Channel72 Feb 04 '11 at 13:41
  • First: Try adding `Py_Initialize();` at the beginning. – Tomek Szpakowicz Feb 04 '11 at 13:45
  • @Tomek, isn't that only necessary if you are going to embed the interpreter in your C-program? – Channel72 Feb 04 '11 at 13:52
  • Have you tried adding `Py_Initialize();`? Did it help? You need to call `Py_Initialize` before using any Python API call. Otherwise Python's internal variables won't be properly initialized; including those used for memory management. – Tomek Szpakowicz Feb 12 '11 at 14:18

1 Answers1

3

Add call to Py_Initialize(); at the beginning of main and try again.

Tomek Szpakowicz
  • 14,063
  • 3
  • 33
  • 55
  • You're right, there's almost certainly some initialisation of either the tuple or long types that is being missed and hence failing on destruction. – ncoghlan Feb 14 '11 at 01:30