Re: INCREF & DECREF

Sjoerd Mullender (Sjoerd.Mullender@cwi.nl)
Tue, 10 Aug 1993 14:53:41 +0200

Guido is on vacation, so I'll try to answer your question. If I am
wrong somebody will no doubt correct me.

On Tue, Aug 10 1993 Lars Tafjord wrote:

> I am still a newcomer to Python and have a few annoying core-dump
> problems. Could someone give some hints on _why_ and _how_ I should
> use INCREF, DECREF, XDECREF and any other related functions/macros?

Use XINCREF or XDECREF instead of INCREF/DECREF when the argument may
be NULL.

The basic idea is, if you create an extra reference to an object, you
must INCREF it, if you throw away a reference to an object, you must
DECREF it. Functions such as newstringobject, newsizedstringobject,
newintobject, etc. create a reference to an object. If you want to
throw away the object thus created, you must use DECREF.

If you put an object into a tuple, list, or dictionary, the idea is
that you usually don't want to keep a reference of your own around, so
Python does not INCREF the elements. It does DECREF the old value.
This means that if you put something into such an object using the
functions Python provides for this, you must INCREF the object if you
want to keep a separate reference to the object around. Also, if you
replace an element, you should INCREF the old element first if you
want to keep it. If you didn't INCREF it before you replaced it, you
are not allowed to look at it anymore, since it may have been freed.

Returning an object to Python (i.e., when your module function
returns) creates a reference to an object, but it does not change the
reference count. When your module does not keep another reference to
the object, you should not INCREF or DECREF it. When you do keep a
reference around, you should INCREF the object. Also, when you return
a global object such as None, you should INCREF it.

If you want to return a tuple, you should consider using mkvalue.
Mkvalue creates a new tuple with a reference count of 1 which you can
return. If any of the elements you put into the tuple are objects,
they are INCREFfed by mkvalue. If you don't want to keep references
to those elements around, you should DECREF them after having called
mkvalue.

Usually you don't have to worry about arguments. They are INCREFfed
before your function is called and DECREFfed after your function
returns. When you keep a reference to an argument, you should INCREF
it and DECREF when you throw it away. Also, when you return an
argument, you should INCREF it, because returning the argument creates
an extra reference to it.

If you use getargs() to parse the arguments, you can get a reference
to an object (by using "O" in the format string). This object was not
INCREFfed, so you should not DECREF it. If you want to keep the
object, you must INCREF it yourself.

If you create your own type of objects, you should use NEWOBJ to
create the object. This sets the reference count to 1. If you want
to throw away the object, you should use DECREF. When the reference
count reaches 0, the dealloc function is called. In it, you should
DECREF all object to which you keep references in your object, but you
should not use DECREF on your object. You should use DEL instead.

Sjoerd Mullender
CWI, dept. CST, Kruislaan 413, 1098 SJ Amsterdam, Netherlands
email: Sjoerd.Mullender@cwi.nl fax: +31 20 592 4199
phone: +31 20 592 4127 telex: 12571 mactr nl