[Numpy-discussion] Some questions about PyArray_As2D.

Konrad Hinsen hinsen at cnrs-orleans.fr
Fri Dec 13 03:12:02 EST 2002

> The function prototype says:
> extern int PyArray_As2D(PyObject **op, char ***ptr, int *d1, int *d2, 
> int typecode)

You are right that my first comment doesn't quite apply, I hadn't
noticed the two stars...

But the code is still OK, it is the calling routine that is responsible
for avoiding memory leaks.

> is exactly what you do with the instruction:
> *op = (PyObject *)ap;
> So you create a new PyArrayObject (allocating another memory area) by 
> means of PyArray_ContiguousFromObject and names it ap, then you modify 
> the memory address which op points to with the above instruction. Now 

Right. This routine cannot know if that reference contains an "owned"
or a "borrowed" reference. In the first case, the reference counter
of the original array must be decreased, in the second case not.

Assume for example that the calling routine got an array passed in
as a borrowed reference:

void foo(PyObject *array)
   /* I want a 2D version! */
   PyArray_As2D(&array, ...)

In that case, decreasing the reference count in PyArray_As2D would
be disastrous.

In the case of an owned reference, the calling routine must keep a
copy of the pointer, call PyArray_As2D, and then decrease the
reference counter on the original pointer. This ought to be easier.
In fact, the interface of PyArray_As2D is pretty badly designed.
It should not overwrite the original pointer, but return a new
one. I also don't see the point in passing all the array information
in additional arguments - they are easy to obtain from the new
array object.

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