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

时间:2017-01-25 14:51:19

标签: arrays memory cython smart-pointers

我正在为带有签名

的函数调用编写Python包装器

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

需要在我的Python包装器中构建arrayIn。一个可能的解决方案是here.但是,由于Cython包含对智能指针的支持,我宁愿实现该解决方案。一种方法是a combination of malloc and a unique_ptr with a custom deleter.另一种(更简单的)解决方案是使用the allocator class from 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负责ndarray,而unique_ptr应对double *[]创建的allocator负责。这是正确的,还是代码会造成内存泄漏?有没有办法可以验证一切都已正确解除分配?

1 个答案:

答案 0 :(得分:1)

  

这是正确的,还是代码会造成内存泄漏?

我不认为这应该泄漏。

  

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

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

在更复杂的情况下,还有其他方法可以测试内存泄漏:C库的调试版本会告诉您是否已经释放了所分配的所有内存。此外,还有valgrindclang' leaksanitizer等工具,但在您的情况下,我会选择循环播放。