从 python 中的共享库返回的数组 - 这是内存泄漏吗?

Posted

技术标签:

【中文标题】从 python 中的共享库返回的数组 - 这是内存泄漏吗?【英文标题】:array returned from shared library in python - is this a memory leak? 【发布时间】:2014-12-10 18:50:39 【问题描述】:

我正在处理的项目有问题,并且不确定最好的解决方法 解决它。

基本上,我将一个慢速 python 算法推入一个 c++ 共享库,我用它来做很多数字密集型的工作。其中一个 c++ 函数的形式为:

const int* some_function(inputs)

//does some stuff
int *return_array = new int[10];

// fills return array with a few values

return return_array;

即在这里返回一个数组。这个数组是在 python 中使用 numpy ndpointer 解释的:

lib.some_function.restype = ndpointer(dtype=c_int, shape=(10,))

我有几个问题困扰了一段时间:

1) 我在这里动态分配了内存。鉴于我通过共享库调用此函数并进入 python,我会导致内存泄漏吗?我的程序运行时间很长,我可能会调用这个函数数百万次,所以这很重要。

2) 我可以使用更好的数据结构吗?如果这是一个纯 c++ 函数,我会返回一个向量,但是通过谷歌搜索,这似乎是带有 ctypes 的 python 中的非理想解决方案。我在 c++ 库中还有其他调用此函数的函数。鉴于我刚刚编写了函数并且即将编写其他函数,我知道在这些函数中使用后删除[]返回的指针。但是,我对目前的情况并不满意,好像不是我自己(或者实际上是几个月后的我自己)使用了这个功能,未来内存泄漏的可能性相对较高。

谢谢!

【问题讨论】:

【参考方案1】:

是的,您正在泄漏内存。 Python 代码不可能自动释放指向的内存(因为它不知道它是如何分配的)。您需要提供相应的解除分配函数(调用delete[])并告诉Python 如何调用它(可能使用@RichardHidges 推荐的包装框架)。

【讨论】:

谢谢,你有这种行为的例子吗?是不是只有动态分配的对象需要被python解除分配? 为什么不简单地将数组作为参数传递呢?这样库就不必担心分配和释放内存。 @eryksun 如果调用者提前知道大小,这可能会起作用。 固定大小的数组更简单。如果大小是可变的,则数组大小可以有第二个参数,以字节或元素为单位。在两遍调用中,调用者将大小传递为 0 以查询所需的大小,这通常是函数返回值。【参考方案2】:

您可能需要考虑使用 SWIG 或 boost::python

这里有一个使用 boost::python 将 std::vector 转换为 python 列表的示例: std::vector to boost::python::list

这里是 swig 的链接: http://www.swig.org

【讨论】:

以上是关于从 python 中的共享库返回的数组 - 这是内存泄漏吗?的主要内容,如果未能解决你的问题,请参考以下文章

从 Python 调用 C++ 64 位共享库

从堆栈跟踪中查找共享库中的源代码行

Python 给定一个包含 N 个整数的数组 A,返回在 O(n) 时间复杂度内不会出现在 A 中的最小正整数(大于 0)

Python 和 C++ 共享相同的内存资源

在 Dalvik 中的两个进程之间共享内存

python可以做数据分析吗?