Yeah, this is a pretty important statement:

"If data is passed to PyArray_NewFromDescr or PyArray_New, this memory
must not be deallocated until the new array is deleted."

So if you dont keep a reference to "data"  in the calling scope, then
python will free that memory once you lose the reference, and you will
segfault. If you hold on to the data for the duration of the call, you
should be ok. But like suggested in the docs, if the data is a python
object, just incref it. But dont forget to set base member pointer
(PyObject *PyArray_BASE(PyObject* arr)) to point to the python data
object, or else you leak a reference, and the memory will never get
freed.

Cheers,

Chris


On Sun, Nov 15, 2009 at 2:31 AM, Matthew Brett <[email protected]> wrote:
> Hi,
>
> On Sat, Nov 14, 2009 at 5:13 PM, Chris Colbert <[email protected]> wrote:
>> AFAIK, you only have to INCREF the dtype. And only for numpy array
>> creation routines that take a dtype object as an argument (they
>> "steal" a dtype reference, which is why you have to incref it).
>
> In case it's useful, here's the scratchpad I'm using for testing:
>
> http://github.com/matthew-brett/arraymakers
>
> (see arraymaker1.pyx).  The reason I think that 'data' needs to be
> INCREF'd is the Warning here:
>
> http://docs.scipy.org/doc/numpy/reference/c-api.array.html#from-scratch
>
> and the fact that I get segfaults if I don't do it.  For example,
> commenting out the Py_INCREF(data) around line 34 of arraymaker1.pyx
> in the repository above, results in a segmentation fault in
> test_arraymaker2.py:
>
> mb...@millroad:~/dev_trees/arraymakers$ nosetests test_arraymaker2.py
> test_arraymaker2.test_arraymaker2(False,) ... ok
> test_arraymaker2.test_arraymaker2(array([0, 1, 2, 3, 4, 5, 6, 7, 8,
> 9], dtype=int16), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int16))
> ... ok
> test_arraymaker2.test_arraymaker2(False,) ... ok
> test_arraymaker2.test_arraymaker2(array([0, 1, 2, 3, 4, 5, 6, 7, 8,
> 9], dtype=int16), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int16))
> ... ok
> test_arraymaker2.test_arraymaker2(False,) ... ok
> test_arraymaker2.test_arraymaker2(array([0, 1, 2, 3, 4, 5, 6, 7, 8,
> 9], dtype=uint32), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
> dtype=uint32)) ... ok
> test_arraymaker2.test_arraymaker2(False,) ... ok
> test_arraymaker2.test_arraymaker2(array([0, 1, 2, 3, 4, 5, 6, 7, 8,
> 9], dtype=uint32), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
> dtype=uint32)) ... ok
> test_arraymaker2.test_arraymaker2(False,) ... ok
> test_arraymaker2.test_arraymaker2(array([ 0.,  1.,  2.,  3.,  4.,  5.,
>  6.,  7.,  8.,  9.]), array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,
> 8.,  9.])) ... ok
> test_arraymaker2.test_arraymaker2(False,) ... ok
> Segmentation fault
>
> Best,
>
> Matthew
> _______________________________________________
> Cython-dev mailing list
> [email protected]
> http://codespeak.net/mailman/listinfo/cython-dev
>
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to