python-c-api引用计数

时间:2016-01-24 19:36:02

标签: python python-c-api

我的python代码将一些字典和列表传递给C,如下所示:

if (!PyArg_ParseTuple(args, "O!lO!O!O!O!O!", &PyList_Type,&list,&los,&PyDict_Type,&entity_len,&PyDict_Type,&inlist_len,&PyList_Type,&inindex,&PyDict_Type,&inlist,&PyList_Type,&tokens))
        return NULL; 

可以获得这样的物品吗?

int i = PyInt_AS_LONG(PyList_GetItem(PyDict_GetItem(inlist,PyList_GetItem(tokens,pi)),current_index[pi]))

我需要在python中调用我的C函数10K次,并且在运行我的代码大约100次后,它会显示段错误11.如何修复它?

1 个答案:

答案 0 :(得分:1)

我不建议你,你应该对PyDict_GetItemPyList_GetItem进行错误检查:

PyObject *obj = PyList_GetItem(args)
if(!obj){
    return NULL
}
// Same for PyDict_GetItem with the difference
// that PyDict won't set an exception, so you 
// probably need to set it yourself.

当出现问题时,*_GetItem个函数都返回NULL。因此,如果您只是在没有正确错误检查的情况下链接这些调用,那么如果其中一个返回NULL,您将遇到问题。

此外,这两个功能 return a borrowed reference to the Object

  

借用拥有引用的好处是你不需要处理通过代码的所有可能路径上的引用 - 换句话说,借用引用你在过早退出时不要冒泄漏的风险。 借用拥有的缺点是,在一些微妙的情况下,在看似正确的代码中借用的引用可以在其借用的所有者实际上已经处理之后使用。

(强调我的)

所以你通常不应该担心Py_DECREF他们。不过要小心;如果您需要使用引用,存储它或将其传递到其他地方,应该增加它的引用并获得它的所有权。

最后,当你将借用的引用传递给PyDict时,我并不是100%确定效果是什么。在文档中找不到任何东西。看一下source for PyDict_GetItem,我看不到DECREF key参数,所以我觉得那里不应该有问题。