将cython分配的缓冲区传递给python
我知道如何将Cython malloc’ed数据传递给Python。但是,我想知道在返回之前强制转换到memoryview是否可以避免内存泄漏:将cython分配的缓冲区传递给python,python,memory-management,cython,Python,Memory Management,Cython,我知道如何将Cython malloc’ed数据传递给Python。但是,我想知道在返回之前强制转换到memoryview是否可以避免内存泄漏: def someCythonFunction(): try: mPtr = <double *>PyMem_Malloc(N * M * sizeof(double) for n in range(N): for m in range(M): m
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对象的生存期联系起来(在您链接到的示例中,内存在析构函数中被释放)。最简单且推荐的方法是使用numpy数组或标准库
array
array(或您选择的其他库)
如果无法避免使用malloc
。您可以为其分配一个您选择的用于销毁的回调函数,并且可以愉快地将其分配给MemoryView:
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
cdef双[:,:]mview
cdef double*mPtr=PyMem_Malloc(N*M*sizeof(double))
a=cython.view.array(shape=(N,M),itemsize=sizeof(double),format=“d”,
mode=“C”,allocate\u buffer=False)
a、 数据=mPtr
a、 回调\u free\u data=PyMem\u free
mview=a
您可以安全地返回
a
或mview
(如果您返回a
,则无需费心处理mview
),它们将在正确的时间正确返回。这是不安全和不正确的。它在函数结束时释放内存,这意味着您返回的指针立即无效
您需要将内存的生存期与Python对象的生存期联系起来(在您链接到的示例中,内存在析构函数中被释放)。最简单且推荐的方法是使用numpy数组或标准库array
array(或您选择的其他库)
如果无法避免使用malloc
。您可以为其分配一个您选择的用于销毁的回调函数,并且可以愉快地将其分配给MemoryView:
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
cdef双[:,:]mview
cdef double*mPtr=PyMem_Malloc(N*M*sizeof(double))
a=cython.view.array(shape=(N,M),itemsize=sizeof(double),format=“d”,
mode=“C”,allocate\u buffer=False)
a、 数据=mPtr
a、 回调\u free\u data=PyMem\u free
mview=a
您可以安全地返回
a
或mview
(如果您返回a
,则无需麻烦mview
),它们将在正确的时间正确返回。您告诉我,这一点很明显。我的印象是它正在工作,因为尽管指针已被释放,但在Python世界中,数据仍然可以访问并且没有损坏。但那可能只是巧合。现在你告诉我这很明显。我的印象是它正在工作,因为尽管指针已被释放,但在Python世界中,数据仍然可以访问并且没有损坏。但这可能只是巧合。