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

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)的文档,您可以看到在Otypecode下,它表示传入的引用计数object加1(注意:该页面的前一部分描述了Otypecode PyArg_ParseTuple,它不会增加引用计数,但在这里也不相关).

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

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

你应该检查Py_BuildValue调用的结果,因为你还需要numPy_BuildValue失败的情况下释放(即返回NULL).