python - PyArray_SimpleNewFromData

标签 python c python-3.x numpy

所以我试图编写一个 C 函数,它接受一个 numpy 数组对象,提取数据,进行一些操作并返回另一个 c 数组作为一个 numpy 数组对象。一切都无缝运行,我使用 python 包装器,这有助于在 python 端轻松操作。但是,我正面临内存泄漏。我有一个 double 输出指针,我对其进行了 malloc 处理,并在将其返回给调用 python 函数之前将其包装到一个 Python 数组对象中,

PyObject *arr;
int nd = 2;
npy_intp dims[] = {5, 10};
double *data = some_function_that_returns_a_double_star(x, y, z);

arr = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, (void *)data);
return arr;

然而,这会造成内存泄漏,因为数据永远不会被释放,我做了一些谷歌搜索,发现这是此类应用程序中的一个问题,解决方案并非易事。我在这方面找到的最有用的资源是 given here .我无法实现此页面从给定示例中讨论的析构函数。有人可以帮我弄这个吗?更具体地说,我正在寻找类似的东西,
PyObject *arr;
int nd = 2;
npy_intp dims[] = {5, 10};
double *data = some_function_that_returns_a_double_star(x, y, z);

arr = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, (void *)data);
some_destructor_that_plug_memLeak_due_to_data_star(args);
return arr;

最佳答案

您不了解的链接中描述的技术是一个很好的技术:创建一个 Python 对象,该对象知道在销毁时如何释放内存,并使其成为返回数组的基础。

听起来您可能对创建新扩展类型的复杂性感到不知所措。幸运的是,这不是必需的。 Python 附带了一种类型,旨在在销毁时执行任意 C 级清理:capsules ,它将一个指针和一个析构函数捆绑在一起,并在胶囊被销毁时调用析构函数。

要为你的内存创建一个胶囊,首先,我们定义一个析构函数:

void capsule_cleanup(PyObject *capsule) {
    void *memory = PyCapsule_GetPointer(capsule, NULL);
    // I'm going to assume your memory needs to be freed with free().
    // If it needs different cleanup, perform whatever that cleanup is
    // instead of calling free().
    free(memory);
}

然后你将一个胶囊设置为你的阵列的基础
PyObject *capsule = PyCapsule_New(data, NULL, capsule_cleanup);
PyArray_SetBaseObject((PyArrayObject *) arr, capsule);
// Do not Py_DECREF the capsule; PyArray_SetBaseObject stole your
// reference.

这应该确保您的内存在不再使用时被释放。

关于python - PyArray_SimpleNewFromData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52731884/

相关文章:

c - 使用 scanf() 格式化输入

c - 如何使用文本文件的内容(制表符分隔格式)来重命名文件夹中的文件?

c - 如何删除一个元素来对数组进行排序

python - 如何提高涉及生成器和嵌套 for 循环的代码的效率

python - 通过字典列表中的关键字保留重复项

python-3.x - python : finding all pallindromic sequences of length k that sum to n

python - 在系统调用期间捕获/阻塞 SIGINT

python - 如何捕捉 IndentationError

python - 保留文本文件每一行的最后一个字,删除其余部分

python - 使用 matplotlib 将标签居中放置在圆圈内