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
