1

下面显示的某些类型的代码导致我在通过 Cython 调用的 C++ 代码中出现内存损坏。我已经设法解决它,但想问什么是最低限度要求是多少。

认为:

  • CFoo是一个 C++ 类,其中一些成员set_ptr采用指向双精度的指针。Cython 类Foo拥有一个指向CFoo.
  • 在某种bar方法内Foo
    • 通过调用创建瞬态numpy.array, 。afunction_returning_a_numpy_array()
    • 创建一个类型化的内存视图a_view以供查看a
    • 一个指针 froma_view被发送到CFoousingCFoo的成员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's 成员可以找到areclaimed 的内存。我已经通过创建a一个成员解决了这个问题Foo。我的问题是:

  • 这会通过使double *(设置为&a_view[0])成为 的成员来解决Foo吗?我猜没有。

  • 这会通过使double a_view[:](设置为a)成为 的成员来解决Foo吗?我在文档中找不到任何解决此问题的方法。

4

1 回答 1

1

使double*a 的成员Foo无济于事(如您所料),因为 refcount ofa没有增加。

使double a_view[:]a 成员会有所帮助(尽管文档中没有明确说明)。我能看到的最好的提示是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数组的两个引用(我不知道为什么)

于 2016-03-04T17:22:59.763 回答