Confusing Reference Ownership: How To Properly Deallocate (via Py_DECREF) Objects Of An Object?
Solution 1:
1) It is necessary to increase the reference count in insert
because its reference count will be automatically decreased at the end of insert. Cython does not know you are storing the object for later. (You can inspect the generated C code to see the DECREF
at the end of the function). If insert
is called with an object of reference count 1 (i.e. .insert(SomeObject())
, then the object would be destroyed at the end of insert without the INCREF
2) If the object is removed from the cfiboheap
during extract
then you should do a DECREF
to acknowledge the fact that you no longer hold it. Cast it to object first (so you still hold a reference to it)
cdef void* ret = cfiboheap.fh_extractmin(self.treeptr) # refcount is 1 here (from the INCREF when it was stored)
if ret==NULL:
# ...
ret_obj = <object>ret
# reference count should be 2 here - one for being on the heap and one for ret_obj. Casting to object increases the refcount in Cython
Py_DECREF(ret_obj) # 1 here
return ret_obj
3) Honestly you try not to use PyObject*
if you can avoid it! It's much better to let Cython do the work. If you can't avoid it then you just need to ensure INCREF
is called once when you store the object, and DECREF
is called once when you stop storing it.
4) You do need to decref the remaining objects on the heap in __dealloc__
. A very easy way to do that might be to all extract
until the cfiboheap
is empty:
try:
while True:
self.extract()
except IndexError:
pass # ignore the error - we're done emptying the heap
A comment about the use of capsules: who owns the fibheap_el
that they point to (and when does this get destructed)? If it gets destructed when the cfiboheap
gets destructed then you have the issue of a capsule with an invalid pointer still being alive. Using this capsule somewhere might end up causing problems. If it doesn't get destructed by the cfiboheap
then you potentially have another memory leak.
Post a Comment for "Confusing Reference Ownership: How To Properly Deallocate (via Py_DECREF) Objects Of An Object?"