键入的Memoryview是否会增加numpy.array';s参考计数? 下面的一些代码,导致我通过Cython调用C++代码中的内存损坏。我已经设法解决了这个问题,但想问一下解决这个问题的最低要求是什么
假设:键入的Memoryview是否会增加numpy.array';s参考计数? 下面的一些代码,导致我通过Cython调用C++代码中的内存损坏。我已经设法解决了这个问题,但想问一下解决这个问题的最低要求是什么,numpy,cython,memoryview,Numpy,Cython,Memoryview,假设: 代码> CFoo < /C>是一个C++类,其中一些成员使用代码> SETIGPTR 。Cython类Foo持有指向CFoo的指针 在Foo的一些条方法中: 瞬态numpy.array,A,通过调用函数返回\u A\u numpy\u array()创建 为查看A,创建了一个键入的内存视图A\u视图 使用CFoo的成员set\ptr将A\u视图中的指针发送到CFoo 片段: cdef class Foo: cdef CFoo *foo_imp; ...
-
<>代码> CFoo < /C>是一个C++类,其中一些成员使用代码> SETIGPTR 。Cython类
Foo
持有指向CFoo
的指针
Foo
的一些条方法中:
- 瞬态
numpy.array
,A
,通过调用函数返回\u A\u numpy\u array()
创建
- 为查看
A
,创建了一个键入的内存视图A\u视图
- 使用
CFoo
的成员set\ptr
将A\u视图中的指针发送到CFoo
cdef class Foo:
cdef CFoo *foo_imp;
...
def bar(self):
a = function_returning_a_numpy_array()
cdef double a_view[:] = a
foo_imp.set_ptr(&a_view[0])
注意,在这个问题的上下文中,对Foo
的后续调用将导致CFoo
对这个指针进行操作
很明显,由于没有任何东西保存a
,对Foo
成员的后续调用可以找到a
的内存。我通过使a
成为Foo
的成员解决了这个问题。我的问题是:
- 将
(设置为double*
)设置为&a_视图[0]
的成员可以解决此问题吗?我猜不会Foo
- 将
(设置为双a_视图[:]
)作为a
的成员,可以解决这个问题吗?我在文档中找不到任何以这种或那种方式解决这个问题的东西Foo
加倍*
成为Foo
的成员不会有帮助(正如您所猜测的),因为a
的refcount不会增加
将双a_视图[:]
设置为成员将有所帮助(尽管文档中没有明确说明)。我能看到的最好的提示是,代码示例显示您可以从内存视图的base
属性检索原始对象
可以使用sys.getrefcount
from __future__ import print_function
import sys
import numpy as np
def f():
a = np.zeros((5,))
print(sys.getrefcount(a))
cdef double[:] b = a
print(sys.getrefcount(a))
运行此命令,第一行打印1,第二行打印3。因此,内存视图似乎实际上存储了对numpy数组的两个引用(我不知道为什么)这是一个很好的答案-谢谢。我有点担心它会从ReCube之类的东西中推断出来,因为它是一个可能会改变的实现(因为这个原因,我没有看Cython生成的C++代码)。然而,这是一个聪明的测试。