我知道this post关于将Cython malloc&#39的数据传递给Python。但是我想知道在返回之前是否转换到内存视图会避免内存泄漏:
def someCythonFunction():
try:
mPtr = <double *>PyMem_Malloc(N * M * sizeof(double)
for n in range(N):
for m in range(M):
mPtr[m + n*M]= ...
return <double[:N,:M]> mPtr
finally:
print("In cython %d" % <int>mPtr)
PyMem_Free(mPtr)
然后在Python中:
mView = someCythonFunction()
这样安全吗?
答案 0 :(得分:2)
这是不安全和不正确的。当函数结束时,它会释放内存,这意味着你返回的指针立即无效。
您需要将内存的生命周期与Python对象的生命周期联系起来(如在链接的示例中,内存在析构函数中释放)。最简单和推荐的方法是使用numpy数组或标准库array
数组(或您选择的其他库)。
如果您无法避免使用malloc
,则可以使用cython.view.array
class。您可以为其分配一个您选择的回调函数,以便在销毁时使用,并且可以很高兴地将其分配给内存视图:
cdef double[:,:] mview
cdef double* mPtr = <double *>PyMem_Malloc(N * M * sizeof(double))
a = cython.view.array(shape=(N, M), itemsize=sizeof(double), format="d",
mode="C", allocate_buffer=False)
a.data = <char *> mPtr
a.callback_free_data = PyMem_Free
mview = a
您可以放心地返回a
或mview
(如果您返回a
,那么就不需要打扰mview
),他们会在正确的时间得到正确的答案