如何通过指针和索引遍历Cython中连续double数组的视图?
修复Cython指针引用报错问题
错误原因
你遇到的报错是因为arr[::1]会生成一个临时的array.array对象,这个对象没有被Python变量持有引用。Cython担心垃圾回收机制会回收这个临时对象,导致view指向的内存失效,进而ptr变成悬空指针,因此抛出“Storing unsafe C derivative of temporary Python reference”错误。
修复方案
方案1:保留切片后的数组引用
先将切片结果存入一个Python变量,确保临时对象不会被回收,再基于该变量创建memoryview:
from cpython cimport array import array arr = array.array("d", (1,2,3,4)) # 保存切片后的数组,避免临时对象被垃圾回收 cdef array.array sliced_arr = arr[::1] cdef double[::1] view = sliced_arr cdef unsigned l = len(view) cdef double *ptr = view.as_doubles # 遍历元素累加 cdef double acc = 0.0 cdef unsigned i for i in range(l): acc += ptr[i]
方案2:直接从原数组创建memoryview
如果原数组本身是连续存储的(array.array默认是连续的),arr[::1]等价于原数组,可直接跳过切片步骤,从原数组创建memoryview:
from cpython cimport array import array arr = array.array("d", (1,2,3,4)) # 直接基于原数组创建memoryview,无需临时切片对象 cdef double[::1] view = arr cdef unsigned l = len(view) cdef double *ptr = view.as_doubles # 遍历元素累加 cdef double acc = 0.0 cdef unsigned i for i in range(l): acc += ptr[i]
内容的提问来源于stack exchange,提问作者Sylvain Leroux
相关产品推荐
相关产品推荐

