Nés*_*tor 8 c python memory extension-methods memory-leaks
我有一个巨大的内存泄漏问题涉及我正在开发的C扩展.在C中,我有一个双精度数组A
和一个名为int变量的变量AnotherIntVariable
,我想传递给Python.好吧,在我的C-extension模块中,我执行以下操作:
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)
Run Code Online (Sandbox Code Playgroud)
所以在Python中我收到这个列表和这样的int:
Pyt_A,Pyt_int=MyCModule.MyCFunction(...)
Run Code Online (Sandbox Code Playgroud)
其中Pyt_A和Pyt_int是列表和我从C扩展名" MyCModule
" 得到的整数,来自MyCFunction
我之前描述的函数" ".
问题是,在Python中,我使用这个Pyt_A
数组(这就是为什么我使用Py_BuildValue
而不是简单的return
语句,为了从垃圾收集器中保存这个变量而做一个INCREF)然后我需要以某种方式取消引用它为了释放分配的内存.问题是我MyCFunction
多次使用该函数,这会产生内存泄漏,因为我不知道如何取消引用我在python中获取的数组以便摆脱它.
我尝试通过return lst
在代码的C部分而不是代码中返回数组Py_BuildValue("Oi",lst,AnotherIntVariable)
,但是当我尝试在python中使用它时,这只会导致分段错误(可能是因为垃圾收集器完成了他的工作)...
......我在这里失踪了什么?有谁能够帮我?
nco*_*lan 12
如果查看Py_BuildValue
(http://docs.python.org/3/c-api/arg.html#c.Py_BuildValue)的文档,您可以看到在O
typecode下,它表示传入的引用计数object加1(注意:该页面的前一部分描述了O
typecode PyArg_ParseTuple
,它不会增加引用计数,但在这里也不相关).
因此,在调用之后Py_BuildValue
,列表的引用计数是2
,但您只希望它1
.
而不是Py_BuildValue
直接返回结果,将其保存到PyObject
指针,减少lst
引用计数,然后返回结果.
你应该检查Py_BuildValue
调用的结果,因为你还需要num
在Py_BuildValue
失败的情况下释放(即返回NULL
).