python解释器如何处理对象的负引用计数?

时间:2014-07-04 09:31:55

标签: python python-c-api

如果对象的引用计数为负,那么python解释器会释放对象的内存吗?

例如,如果我有这样的代码,time_tuple将被python释放?

PyObject* list = PyList_New(2);
PyObject *time_tuple = Py_BuildValue("(s, s)", "Time", "O");
PyList_SetItem(list, 0, time_tuple);
Py_XDECREF(time_tuple);
Py_XDECREF(list);

如果可以的话,请参考你答案中的一些文件。

1 个答案:

答案 0 :(得分:2)

解释器不应该遇到负引用计数。如果引用计数达到零,则意味着对该对象的引用为零。一旦发生这种情况,该对象将被解除分配。

引用Python documentation

  

如果引用计数达到零,则调用对象的类型的释放函数(不能为NULL)。

另请参阅here了解更多信息。

同样重要的是要注意,在Python中,除了引用计数之外,跟踪实际拥有这些引用的人是很重要的。

在您提供的示例中:

  1. Py_BuildValue()会返回一个新的引用,然后由您拥有并保存在time_tuple中。此时元组的引用计数为1.

  2. PyList_SetItem()窃取所有权引用,元组的引用计数仍为1,但引用归list所有。

  3. Py_XDECREF(time_tuple)将元组的引用计数减少为0,并释放对象。这是错误,因为引用归list所有。

  4. Py_XDECREF(list)将列表的引用计数减少为0,并且列表被释放。对元组的引用由列表拥有,因此它会减少其引用计数。

  5. 不幸的是,元组已经被分配,你的程序崩溃了。或者更糟糕的是,它可能会继续运行一段时间,在代码的不相关部分崩溃。调试这通常很有趣。