2016-03-04 77 views
1

下面顯示的一些代碼類型導致我在通過Cython調用的C++代碼中損壞內存。我已經設法解決它,但想問什麼是解決它所需的最小。鍵入的MemoryView是否增加numpy.array的引用計數?

假設:

  • CFoo是一個C++類的一些部件set_ptr採用指針的兩倍。 Cython類Foo包含指向CFoo的指針。
  • Foo一些bar方法:
    • 瞬態numpy.arraya,通過調用function_returning_a_numpy_array()創建。
    • 有類型的內存視圖,a_view創建用於查看a。使用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[:](設置爲aFoo的成員解決?我無法在文檔中找到任何解決這種或那種方法的內容。

回答

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數組的兩個引用(我不知道爲什麼)

+0

這是一個很好的答案 - 謝謝。我有點擔心,推斷它是像refcount這樣的東西是確定性的,因爲它是一個可能會改變的實現(因爲這個原因,我沒有看到Cython生成的C++代碼)。儘管如此,這是一個聰明的測試。 –