我正在Cython(0.29)中实现并使用numpy(1.15.1)
cdef double *proj_points[1024]
cdef np.ndarray[double, ndim=2, mode="c"] array_ptr
for i in range(2):
array_ptr = np.ascontiguousarray(self.projection[i] @ points, dtype=np.float)
proj_points[i] = &array_ptr[0, 0]
在第1行中,我定义了指针数组(在堆栈上)。在第2行中,我定义了array_ptr
,用于将numpy数组转换为C风格的指向numpy数组的指针。
当我检查proj_points
中的指针时,它们都指向最后一个numpy数组(即循环中的第二个)的同一存储元素。
如果我执行相同的硬编码:
cdef np.ndarray[double, ndim=2, mode="c"] array_ptr0 = np.ascontiguousarray(self.projection[0] @ points, dtype=np.float)
self.proj_points[0] = &array_ptr0[0, 0]
cdef np.ndarray[double, ndim=2, mode="c"] array_ptr1 = np.ascontiguousarray(self.projection[1] @ points, dtype=np.float)
self.proj_points[1] = &array_ptr1[0, 0]
所有指针都指向相应的numpy数组的第一个值。对于上面的循环情况,我也希望这样做,因为在运行时可能会有可变数量的指针。我该如何修饰呢?
cdef
array_ptr
在循环内,但这在Cython中是非法的(cdef
仅在第一级是允许的)。 cdef
内部函数,但这不起作用答案 0 :(得分:0)
指向数组的指针不是Python参考计数方案的一部分,因此它们不会阻止数组被破坏。
因此,一旦array_ptr
在每个循环开始时被重新分配,Python就会破坏它原来用来保存的数组。这意味着proj_points
的上一个元素现在是指向不再存在的数组的指针,并且如果尝试读取该数组,则得到的结果完全是不确定的。
您需要保留对持有指针的任何numpy数组的Python引用。