[Numpy-discussion] Some questions about PyArray_As2D.

Konrad Hinsen hinsen at cnrs-orleans.fr
Wed Dec 11 10:46:03 EST 2002

> Just done. By the way reading the code again and again I got another 
> question. Here is the complete code fragment:
> extern int PyArray_As2D(PyObject **op, char ***ptr, int *d1, int *d2, 
> int typecode) {
>      PyArrayObject *ap;
>      int i, n;
>      char **data;
>      if ((ap = (PyArrayObject *)PyArray_ContiguousFromObject(*op, 
> typecode, 2, 2)) == NULL)
>          return -1;
>      n = ap->dimensions[0];
>      data = (char **)malloc(n*sizeof(char *));
>      for(i=0; i<n; i++) {
>          data[i] = ap->data + i*ap->strides[0];
>      }
>      *op = (PyObject *)ap;  <=== It doesn't sound good to me!!!
>      *ptr = data;
>      *d1 = ap->dimensions[0];
>      *d2 = ap->dimensions[1];
>      return 0;
> }
> Looking at the marked line I started wondering about the fate of the 
> object originally pointed by op. Without explicitly deallocating it you 
> lost any chance to reach it. It turns out in a memory leakage. 

No. op is an input parameter and thus a "borrowed" reference. It might
not be the best coding style to reuse that variable name for something
unrelated later on, but it doesn't cause a memory leak.

> I'm very interested in this topic because I'm writing some Python 
> extensions and I'd like to understand how I have to handle all these 
> objects correctly. So how "long" does a Python object live? How can I 
> release correctly the allocated memory?

There is an explanation of this topic in chapter 1.10 of the Python
"Extending and Embedding" manual. Basically, you have to increase an
object's reference counter if you want to keep a reference to it
beyond the end of the currently running function, and to decrease the
counter if you want to release that reference. Whenever the reference
count goes to zero, the object is deleted. With very few exceptions,
functions that take an object as input to work on (but not store)
don't increase the reference counter. They don't have to, because
nothing can happen to the object until the function terminates.
Special precautions need to be taken for multithreading, but these go
much beyond object reference counting.

As a rule of thumb, you don't have to worry about reference counting
at all as long as you only write C functions that act on existing
objects. It becomes an issue when you define your own extension types
in C.

Konrad Hinsen                            | E-Mail: hinsen at cnrs-orleans.fr
Centre de Biophysique Moleculaire (CNRS) | Tel.: +33-
Rue Charles Sadron                       | Fax:  +33-
45071 Orleans Cedex 2                    | Deutsch/Esperanto/English/
France                                   | Nederlands/Francais

More information about the NumPy-Discussion mailing list