在 cython 中使用智能指针进行动态分配的数组



我正在为带有签名的函数调用编写一个 Python 包装器

double** foo(double** arrayIn, int dim1, int dim2);

并且需要在我的 Python 包装器中构建arrayIn。这里给出了一个可能的解决方案。但是,由于 Cython 包含对智能指针的支持,因此我更愿意实现该解决方案。一种方法是将 malloc 和带有自定义删除程序的unique_ptr组合在一起。另一个(更简单的)解决方案是使用 libcpp 中的分配器类。

import numpy as np
cimport numpy as np
from libcpp.memory cimport unique_ptr, allocator
def testArray(int dim1, int dim2):
    cdef allocator[double *] ptr_al
    cdef unique_ptr[double *] myptr
    cdef np.ndarray arr
    cdef double[:,:] carr
    myptr.reset(ptr_al.allocate(dim1))
    arr = np.ndarray((dim1,dim2),dtype=np.float64,order='C')
    carr = arr
    myptr.get()[0] = &carr[0,0]
    myptr.get()[1] = &carr[1,0]
    myptr.get()[2] = &carr[2,0]

此代码可以正确编译和执行(使用 Cython 24.1、Python 3.5、VS2015)。我担心的是所有东西是否会被正确释放/垃圾收集。我的理解是Python负责ndarrayunique_ptr应该负责allocator创建的double *[]。这是正确的,还是代码会产生内存泄漏?有没有办法验证所有内容是否已正确解除分配?

这是正确的,还是代码会产生内存泄漏?

我认为这不应该泄漏。

有没有办法验证所有内容是否已正确解除分配?

您可以在循环中调用testArray,并查看进程内存是线性增长还是保持不变。由于您知道dim1dim2,因此您可以估计未正确释放某些内容的内存泄漏大小。

在更复杂的情况下,还有其他方法可以测试内存泄漏:有 C 库的调试版本,它会告诉您是否已释放分配的所有内存。此外,还有像valgrind这样的工具,clangleaksanitizer,但在你的情况下,我会使用循环。

相关内容

  • 没有找到相关文章

最新更新