从分配的数组在C中创建numpy数组会导致内存泄漏

dpitch40

我已经在程序中追踪到我用C语言编写的Python模块的内存泄漏,以有效地解析以ASCII十六进制表示的数组。(例如“ FF 39 00 FC ...”)

char* buf;
unsigned short bytesPerTable;
if (!PyArg_ParseTuple(args, "sH", &buf, &bytesPerTable))
{
    return NULL;
}

unsigned short rowSize = bytesPerTable;
char* CArray = malloc(rowSize * sizeof(char));

// Populate CArray with data parsed from buf
ascii_buf_to_table(buf, bytesPerTable, rowSize, CArray);

int dims[1] = {rowSize};

PyObject* pythonArray = PyArray_SimpleNewFromData(1, (npy_intp*)dims, NPY_INT8, (void*)CArray);
return Py_BuildValue("(O)", pythonArray);

我意识到numpy不知道释放为CArray分配的内存,从而导致内存泄漏。在对该问题进行了一些研究之后,在本文的注释建议下,我添加了以下行,该行应告诉数组它“拥有”其数据,并在删除后释放它。

PyArray_ENABLEFLAGS((PyArrayObject*)pythonArray, NPY_ARRAY_OWNDATA);

但是我仍然遇到内存泄漏。我究竟做错了什么?如何使NPY_ARRAY_OWNDATA标志正常工作?

作为参考,ndarraytypes.h中的文档使它看起来应该可以工作:

/*
 * If set, the array owns the data: it will be free'd when the array
 * is deleted.
 *
 * This flag may be tested for in PyArray_FLAGS(arr).
 */
#define NPY_ARRAY_OWNDATA         0x0004

同样作为参考,以下代码(调用C中定义的Python函数)演示了内存泄漏。

tableData = "FF 39 00 FC FD 37 FF FF F9 38 FE FF F1 39 FE FC \n" \
            "EF 38 FF FE 47 40 00 FB 3D 3B 00 FE 41 3D 00 FE \n" \
            "43 3E 00 FF 42 3C FE 02 3C 40 FD 02 31 40 FE FF \n" \
            "2E 3E FF FE 24 3D FF FE 15 3E 00 FC 0D 3C 01 FA \n" \
            "02 3E 01 FE 01 3E 00 FF F7 3F FF FB F4 3F FF FB \n" \
            "F1 3D FE 00 F4 3D FE 00 F9 3E FE FC FE 3E FD FE \n" \
            "F6 3E FE 02 03 3E 00 FE 04 3E 00 FC 0B 3D 00 FD \n" \
            "09 3A 00 01 03 3D 00 FD FB 3B FE FB FD 3E FD FF \n"

for i in xrange(1000000):
    PES = ParseTable(tableData, 128, 4) //Causes memory usage to skyrocket
增白剂

这可能是一个引用计数问题(来自“如何扩展NumPy”):

引用计数错误的一种常见来源是Py_BuildValue函数。请注意“ N”格式字符和“ O”格式字符之间的区别。如果您在子例程(例如输出数组)中创建一个新对象,并且将其以返回值的元组传递回去,那么您很可能应该在Py_BuildValue中使用'N'格式字符。'O'字符将使引用计数增加一。这将为调用者提供一个全新数组的两个引用计数。当删除变量并将引用计数减一时,仍然会有该额外的引用计数,并且该数组将永远不会被释放。您将有一个引用计数导致的内存泄漏。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

引用数组索引是否会导致内存泄漏?

为什么调用堆栈数组会导致内存泄漏?

为什么Node.js中的全局数组会导致内存泄漏?

为什么类型化数组会导致JavaScript中的内存泄漏

numpy:创建一个空数组会导致内存错误?

打印C链表会导致内存泄漏

动态数组的C ++内存泄漏

分配多维数组后的内存泄漏

Python:创建数组会自动分配内存吗?

Python C API:将PyObjects分配给字典会导致内存泄漏

分配函数作用域成员是否会导致内存泄漏?

C ++中对象数组的静态内存分配

Char * C ++中的数组内存分配

C - 数组中内存的重新分配

从numpy数组创建pandas DataFrame会导致奇怪的错误

在ArrayList的add()方法中创建新对象会导致内存泄漏。我可以做些什么?

将内存分配给 C 中动态增长的字符数组会引发分段错误

从堆和内存泄漏中删除C ++数组

在C中调整二维数组的大小。内存泄漏

C ++中按值乘法的数组内存泄漏

调用创建对象的函数是否会导致内存泄漏?

这会导致c ++中的内存泄漏吗?

如何在python中为numpy数组分配内存?

为什么Objective-C中的“ try catch”会导致内存泄漏?

为什么C#中的Lambda表达式会导致内存泄漏?

在C中操作PNG图像会导致内存泄漏或图像上出现白色条纹

使用动态数组的Valgrind内存泄漏C ++

内存泄漏 C++ 数组列表

C创建超出特定大小的结构数组会导致崩溃