DECREFing and PyArray functions in C Extensions

Louis M. Pecora pecora at anvil.nrl.navy.mil
Mon May 29 14:35:15 EDT 2000


In article <ya04s7hcox1.fsf at trymheim.ifi.uio.no>, Roger Hansen
<rogerha at ifi.uio.no> wrote:

> Now assume I have an extension where a C function should create and
> return a NumPy array.
> 
> static PyObject *
> foo_retarray(PyObject *self, PyObject *args)
> {
>   int length, i;
>   double x;
>   double* a;        
>   PyArrayObject *array;
> 
>   if(!PyArg_ParseTuple(args, "i", &length))
>     return NULL;
> 
>   array = (PyArrayObject *) 
>     PyArray_FromDims(1, &length, PyArray_DOUBLE);
>     
>   a = (double*) array->data;
>   for (i = 0; i < length; i++) {
>     x = (double) i/(length-1);
>     a[i] = f(x);
>   }
> 
>   return PyArray_Return(array);
> }
> 
> Should I DECREF array here before the return? 

I'll take a stab at this and say, no.  Using PyArray_Return(array)
automatically DECREFs the array.


> If we rewrite it like this
> 
> static PyObject *
> foo_retarray2(PyObject *self, PyObject *args)
> {
>   int length, i;
>   double x;
>   double* a;        
> 
>   if(!PyArg_ParseTuple(args, "i", &length))
>     return NULL;
> 
>   a = malloc(length*sizeof(double));
>   for (i = 0; i < length; i++) {
>     x = (double) i/(length-1);
>     a[i] = f(x);
>   }
> 
>   return PyArray_FromDimsAndData(1, &length, PyArray_DOUBLE, (char*) a);
> }
> 
> I'm sure we don't have to DECREF anything. But is this a good way to
> create a NumPy array in C?

Hmmm...I would have said, yes.  You malloc the memory, then return a
pointer, but you Must DECREF when any Pyarray is created, unless you
use return PyArray_Return(obj) or PyArray_BuildValue with the "N"
construct (quoting Travis).  In fact, I would say you have created two
memory leaks.  One with the C array through malloc and the other with
the PyArray created through PyArray_FromDimsAndData.  I don't think the
latter uses the C allocated memory, but allocates its own.  Not sure,
but I would check this out.



More information about the Python-list mailing list