在Python C扩展中处理PyList_Append时,对Py_DECREF / INCREF的遗失

2024-09-30 12:29:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我在处理PyList_append时丢失了Py_DECREF/incrif。有人能对以下代码发表意见吗?在

PyObject * bugmaybe(PyObject *self, PyObject *args)
{
   PyObject * trio=PyList_New(0);
   PyObject * trio_tmp;
   PyObject * otmp = PyFloat_FromDouble(1.2);
   PyList_Append(trio_tmp,otmp);
   //Py_DECREF(otmp);
   otmp = PyFloat_FromDouble(2.3);
   PyList_Append(trio_tmp,otmp);
   //Py_DECREF(otmp);
   PyList_Append(trio,trio_tmp);
   Py_INCREF(trio_tmp);
}

Tags: 代码pyselftriotmppyobjectpylistappend
2条回答

PyList_Append()不会“窃取”引用,因此如果不打算在后面使用附加值,请将其减少。在

另外,不要忘记从函数返回PyObject*,否则系统会认为发生了异常。在

如果您预先知道列表的大小,那么创建具有正确大小的列表并使用PyList_SetItem()通常会更快。在

您的代码完全错误,trio_tmp未初始化。在

试试这个:

PyObject * bugmaybe(PyObject *self, PyObject *args)
{
  PyObject * trio=PyList_New(3);
  PyObject * otmp = PyFloat_FromDouble(1.2);
  PyList_SetItem(trio,0,otmp);
  otmp = PyFloat_FromDouble(2.3);
  PyList_SetItem(trio,1,otmp);
  PyList_Append(trio,2, PyList_New(0));
  return trio;
}

如果您真的想使用PyList_Append,那么您的代码基本上是正常的,只是缺少了trio_tmp的初始化和结尾多余的Py_incrif。在

^{pr2}$

上述代码相当于:

 trio = []
 trio_tmp = []
 otmp = 1.2
 trio_tmp.append(otmp)
 otmp = 2.3
 trio_tmp.append(otmp)
 trio.append(trio_tmp)

希望有帮助。主要的提示是在文档中,如果它说“偷取引用”,那么函数基本上就获得了所有权;如果它说“新引用”,那么它会为你做一个incriff;如果什么也没说,它可能会根据需要执行incrif和DECREF对。在

相关问题 更多 >

    热门问题