[Bf-python] Reference Count Owners Manual
Joseph Gilbert
jgilbert at TIGR.org
Wed Sep 21 21:16:04 CEST 2005
Hello to all,
I'm am getting myself clear on reference count in the C/API and i've put
together a little document to help me :) If anyone would like to
disscuss it or verify ideas presented here that would be great. I would
like to use this personally in my coding efforts and if it's useful, to
also place on the wiki. Anyway without further ado:
---------------------------------------------------------------------------------------------------
OWNING A REFERENCE
Your code takes ownership of a variable when
a) you recieve a variable from a called function that owned the
variable
b) you called Py_INCREF on a borrowed variable
You are responsible to deal with your owned reference by either
a) calling Py_DECREF when you are done with the reference or
b) transferring ownership of the reference by passing it to a caller
c) store it in a container that steals a reference
You are responsible for calling Py_DECREF when the reference is either
a) abandoned (it's will no longer be called), or
b) the reference is overwritten (you have changed the value of the
reference).
Forgetting to dispose of an owned reference creates a memory leak.
Any references returned from a C function that is called from Python
/must be owned/ by the C function.
You /should/ call Py_INCREF and take ownership on a variable when
a) you received a borrowed reference (likely from a container) and
your code calls code that might cause the reference count to be
decremented.
b) you are transferring ownership to a caller and don't currently
own a reference to it
You /should not /call Py_INCREF and take ownership on a variable when
a) you are using a local variable that does not call code that may
decrement it's reference count
C/API Functions beginning with PyObject_, PySequence_, PyMapping_,
PyNumber_ return references that you own.
BORROWING A REFERENCE
Your code borrowed a reference to a variable when
a) it received a variable from a called function that didn't own it
b) it received a variable as an argument
c) you received the variable from a C/API container (likely)
You are responsible to deal with your borrowed reference by
a) not holding on to the reference longer than the owner of the
reference.
b) not calling Py_DECREF on it
c) not transferring ownership of it to a caller without taking
ownership of it
Using a borrowed reference after the owner has disposed of it risks
using freed memory . (crash)
You must never call Py_DECREF on a reference you don't own. (potential
crash)
Functions beginning with PyList_, PyTuple_, PyDict_, etc. return a
borrowed reference.
STOLEN REFERENCES
PyList_SetItem() and PyTuple_SetItem() 'steal' a reference to an object
(i.e. the container doesn't increment the reference count of the object
but is considered the owner)
FUNCTION PASSING
When you call a function and get back an object you either
a) have obtained ownership of the reference because the callee owned
the reference and passed ownership of the object on to you
b) have borrowed the reference because the callee didn't take
ownership of the reference before passing it on
Passing your reference of an object into a called function
a) does not change your responsibility of ownership over the reference
b) causes the called function to receive a borrowed reference
When transferring ownership of an object
a) you pass an object you own directly to the caller without calling
Py_INCREF, or
b) you call Py_INCREF on a borrowed reference and then pass the
object on to the caller
Many functions that extract objects from other objects also transfer
ownership with the reference
DEALLOCATION
When an object's reference count becomes zero
a) the object's deallocator is called
b) all references to child objects should be decremented
MISC
You should not make objects reference each other else they will not be
deallocated correctly because of circular references (GC)
A few sources:
http://docs.python.org/api/refcountDetails.html
http://docs.python.org/api/refcounts.html
http://docs.python.org/ext/refcounts.html
http://starship.python.net/crew/mwh/toext/refcounting-conventions.html
Python in a Nutshell
More information about the Bf-python
mailing list