下面显示的某些类型的代码导致我通过Cython调用的C ++代码中的内存损坏。我设法解决了这个问题,但想问一下解决它所需的最小是什么。
假设:
CFoo
是一个C ++类,其中一些成员set_ptr
获取指向double的指针。 Cython类Foo
包含指向CFoo
。bar
的某个Foo
方法中:
numpy.array
创建暂时a
,function_returning_a_numpy_array()
。a_view
用于查看a
。a_view
的指针使用CFoo
成员CFoo
发送给set_ptr
。段:
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_view[0]
)成为Foo
的成员来解决这个问题吗?我猜不到。
通过将double a_view[:]
(设置为a
)成为Foo
的成员来解决这个问题吗?我无法在文档中找到解决这种或那种方式的任何内容。
答案 0 :(得分:1)
让double*
成为Foo
的成员不会有帮助(正如您猜测的那样),因为a
的引用次数不会增加。
让double a_view[:]
成员会有所帮助(尽管文档中没有明确说明)。我能看到的最佳提示是http://docs.cython.org/src/userguide/memoryviews.html#memoryview-objects-and-cython-arrays,其中代码示例显示您可以从内存视图的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数组的引用(我不知道为什么)