1

I'm building a nested set of tuples in a C++ Python extension. However, I'm having some problems with managing reference counts.

The minimal code to re-create this memory leak:

PyObject *outer = PyTuple_New(outer_size);
for (size_t index = 0; index < outer_size; ++index) {
    PyObject *inner = Py_BuildValue("iiiiiiiiid", ...);
    PyTuple_SetItem(outer, index, inner);
}
Py_CLEAR(outer);
Py_INCREF(Py_None);
return Py_None;

Now, if I instead replace the PyTuple_SetItem(outer, index, inner) with a Py_CLEAR(inner), the memory usage doesn't grow over time.

Am I wrong about the outer tuple stealing the reference to the inner tuple? Is there some other reason memory wouldn't be reclaimed?

squidpickles
  • 1,737
  • 19
  • 27
  • The code should not leak. I'd add asserts liberally to check the return value of each API function and show the code hiding behind the `...`. – sterin Mar 03 '12 at 04:32

1 Answers1

1

Turns out I was mistaking a very slowly growing memory usage (for other reasons) for a memory leak. Had the reference counting been failing, it would have grown substantially faster. So, it's true. This code doesn't leak.

squidpickles
  • 1,737
  • 19
  • 27
  • In case this is a bit confusing... the code was returning a set of windows detected in an image. It turns out that the list of images I was using just happened to have more windows in each image, therefore using more memory over time. – squidpickles Mar 06 '12 at 00:37