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

时间:2017-06-08 12:39:16

标签: python memory-management cython

我知道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()

这样安全吗?

1 个答案:

答案 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

您可以放心地返回amview(如果您返回a,那么就不需要打扰mview),他们会在正确的时间得到正确的答案