将cython分配的缓冲区传递给python

将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

我知道如何将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):
                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世界中,数据仍然可以访问并且没有损坏。但这可能只是巧合。