Hi,

> When you commented out the INCREF on the datat, did you also comment
> out PyArray_Set_BASE? If not, that may have been causing the problem.
> If you set the base without INCREF'ing the data, then numpy will
> DECREF that data when python goes to gc the array. Now you've lost a
> reference, and if it went to zero, python then tries to gc an object
> that's still in scope.

Ah - yes - you are right.  Commenting out the Base line removes the
segfault.  Just for my own sake I'm going to summarize, often
repeating what you've said above:

Given this line:

arr = PyArray_NewFromDescr(&PyArray_Type, 1,  dt, 1, &size, NULL,
<void *>ptr, 0, <object>NULL)

The array now points into the memory at `ptr`.   The memory at `ptr`
needs to stay around for as long as I want to use the array.   In my
example, as you've pointed out, I passed in `data`, from which I got
`ptr`, and `data` therefore exists in the surrounding scope, and will
support `ptr`, at least in the surrounding scope.

When I add:

PyArray_Set_BASE(arr, data)

this _borrows_ a reference to the object `data`, and stores it in the
array.   When the array is garbage collected, `data` is DECREF'd so
that `data` in the surrounding scope has been busted by the DECREF on
array garbage collection.

However, if I had created `data` in the original 'make_1d_array`
function, rather than passing it in, I'd need to do as I have done,
which is INCREF the data so that it does not get garbage collected
when I leave the function scope, and PyArray_Set_BASE so that the
array knows to DECREF `data` and allow garbage collection when it goes
out of scope.

I don't know whether that is clear, but it was my best shot...

Cheers,

Matthew
_______________________________________________
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to