gpt4 book ai didi

python - Python 中的 C 扩展 - 返回 Py_BuildValue() 内存泄漏问题

转载 作者:IT王子 更新时间:2023-10-28 23:35:28 31 4
gpt4 key购买 nike

我有一个巨大的内存泄漏问题,涉及我正在开发的 C 扩展。在 C 语言中,我有一个名为 A 的 double 组和一个名为 AnotherIntVariable 的 int 变量,我想将它们传递给 Python。好吧,在我的 C 扩展模块中,我执行以下操作:

int i;  
PyObject *lst = PyList_New(len_A);
PyObject *num;
if(!lst)
return NULL;
for(i=0;i<len_A;i++){
num=PyFloat_FromDouble(A[i]);
if(!num){
Py_DECREF(lst);
return NuLL;
}
PyList_SET_ITEM(lst,i,num);
}
free(A);
return Py_BuildValue("Oi",lst,AnotherIntVariable)

所以在 Python 中我收到了这个列表和这样的 int:

Pyt_A,Pyt_int=MyCModule.MyCFunction(...)

其中 Pyt_A 和 Pyt_int 是我从 C 扩展“MyCModule”和我之前描述的函数“MyCFunction”获得的列表和整数。

问题在于,在 Python 中,我使用了这个 Pyt_A 数组(这就是我使用 Py_BuildValue 而不是简单的 return 语句的原因, 做一个 INCREF 以便从垃圾收集器中暂时保存这个变量)但是我需要以某种方式取消引用它以释放分配的内存。问题是我多次使用 MyCFunction 函数,这会产生内存泄漏,因为我不知道如何取消引用我在 python 中获得的数组以摆脱它。

我尝试通过在代码的 C 部分执行 return lst 而不是 Py_BuildValue("Oi",lst,AnotherIntVariable) 来返回数组,但是当我尝试在python中使用它时只会导致段错误(可能是因为垃圾收集器做了他的工作)......

...我在这里错过了什么?有人可以帮帮我吗?

最佳答案

如果您查看 Py_BuildValue ( http://docs.python.org/3/c-api/arg.html#c.Py_BuildValue ) 的文档,您可以看到在 O 类型代码下,它表示传入对象的引用计数加一(注意:该页面的前面部分描述了 PyArg_ParseTupleO 类型代码,它不会增加引用计数,但在这里也不相关)。

因此,在调用 Py_BuildValue 之后,您的列表的引用计数为 2,但您只希望它为 1

不是直接返回 Py_BuildValue 的结果,而是将其保存到 PyObject 指针,减少 lst 引用计数,然后返回你的结果.

无论如何,您都应该检查 Py_BuildValue 调用的结果,因为如果 Py_BuildValue 失败,您还需要释放 num (即返回 NULL)。

关于python - Python 中的 C 扩展 - 返回 Py_BuildValue() 内存泄漏问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5508904/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com