pythoncython

Cython memoryview pointer to empty array


The Cython docs discuss passing a pointer to a memoryview by using, e.g.:

cdef double[::1] x_view = x  # some array
cdef double* ptr = &x_view[0]

however, when that array x has no elements (x.size == 0), trying to access x_view[0] fails. For the C library to which I am making an interface, passing a NULL pointer leads to a segfault, so I can't just check x.size and pass NULL.

Instead, I need to pass a pointer to a valid memory block of size 0. Using the old numpy array interface and passing <double*>x.data works even in the case of an empty array like x = np.array([]), but I am trying to move to using typed memoryviews with fused types to avoid code duplication and have more easily-enforceable type safety.

Is there an accepted way to handle this situation? Or are there plans for a feature like x_view.ptr that would handle this case internally?


Solution

  • I had to look this up in the Cython source to find it, but memoryviews do have an undocumented attribute _data and thus you can do

    cdef double* ptr = <double*>x_view._data
    

    (the cast is because the data attribute is just typed generically as char*).

    With that said, I'm not completely sure I'd trust it for your purposes for a couple of reasons:

    To me that suggests you should do something like:

    cdef double dummy_double
    cdef double* ptr = &x_view[0] if x_view.shape[0] else &dummy_double
    

    and then you know you're passing a pointer to some valid memory.