首页 > 解决方案 > PyObject_CallMethod 泄漏/段错误

问题描述

我从 C 调用一个 Python 方法,它在 10 小时后在 PyObject_CallMethod 上泄漏/段错误。

你能检查我的代码吗?我的错误在哪里?缺少什么?

C代码:

PyObject *pFrameAsList = PyList_New(0);
...
for (int k=0; k<m_nbImages; ++k)
{
   PyObject *pFrameAsArray = toNDArray(frame);
   ...
   PyList_Append(pFrameAsList, pFrameAsArray);
   Py_DECREF(pFrameAsArray);
}
PyObject *pValue = PyObject_CallMethod(pInstance, "analyseFrame", "(O)", pFrameAsList);
...
Py_INCREF(pValue);
...
for (int k=0 ; k<max; k++ )
{
    PyObject *ptemp = PyList_GetItem(pValue,k);
}
Py_DECREF(pFrameAsList);
Py_DECREF(pValue);

和 Python 代码:

def analyseFrame(self, frame):
   results = self.model.analyse(np.asarray(frame))
   return list(results)

标签: pythoncmemory-leakssegmentation-fault

解决方案


我认为问题在于您不应该有以下行:

Py_INCREF(pValue)

原因是它PyObject_CallMethod已经为您增加了引用计数。如果您进行额外Py_INCREF调用,则给定的引用计数PyObject将永远不会变为 0。

根据文档,PyObject_CallMethod返回一个新的参考

要了解“新参考”的含义,而不是“借用参考”,请查看文档的“参考计数详细信息”部分的第一段:


推荐阅读