首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python CApi引用计数详细信息

Python CApi引用计数详细信息
EN

Stack Overflow用户
提问于 2018-07-09 08:08:00
回答 1查看 534关注 0票数 3

我正在查看这里的一些示例代码( https://docs.python.org/2.0/api/refcountDetails.html ),并试图更好地理解其中两个示例之间的区别:第一个示例是:

代码语言:javascript
复制
PyObject *t;

t = PyTuple_New(3);
PyTuple_SetItem(t, 0, PyInt_FromLong(1L));
PyTuple_SetItem(t, 1, PyInt_FromLong(2L));
PyTuple_SetItem(t, 2, PyString_FromString("three"));

作者解释说,PyTuple_SetItem() 窃取了引用(因此没有必要对其进行DECREF )。好吧,我明白了。然后,作者使用PySequence_SetItem()提供了类似的代码,不窃取引用的,因此调用者必须执行DECREF,示例代码如下所示:

代码语言:javascript
复制
PyObject *l, *x;

l = PyList_New(3);
x = PyInt_FromLong(1L);
PySequence_SetItem(l, 0, x); Py_DECREF(x);
x = PyInt_FromLong(2L);
PySequence_SetItem(l, 1, x); Py_DECREF(x);
x = PyString_FromString("three");
PySequence_SetItem(l, 2, x); Py_DECREF(x);
PyObject *l, *x;

我的问题是,如果第二个示例与第一个示例类似,按如下方式传递PyTYPE_FromSOMETYPE会发生什么?

代码语言:javascript
复制
PyObject *l;

l = PyList_New(3);
PySequence_SetItem(l, 0, PyInt_FromLong(1L));
PySequence_SetItem(l, 1, PyInt_FromLong(2L));
PySequence_SetItem(l, 2, PyString_FromString("three"));

在最后一种情况下是良性的,还是会导致内存泄漏(因为PySequence_SetItem不会获得由PyInt_FromLong和PyString_FromString创建的引用的所有权,调用者也不会对其执行DECREF )??

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-09 08:20:21

它会导致内存泄漏。

创建对象时,它从refcount为1开始。只有当refcount变为0时,该对象才会被删除。

第一个示例引用:当您将新对象传递给一个可以窃取引用(取得所有权)的函数(如PyTuple_SetItem )时,引用计数不会递增,因此它仍然是1。当元组最终被销毁并对其所有元素进行反引用时,计数将下降到0,因此它将被销毁。一切都很好。

第三个示例:当您将新对象传递给不窃取引用(创建新引用)的函数(如PySequence_SetItem )时,引用计数将递增,因此它是2。当元组最终被销毁并对其所有元素进行反引用时,计数将降至1,因此它不会被销毁。而且,由于没有其他人再引用它(除非您将它存储在某个地方),所以任何人都不可能破坏它。所以它被泄露了。

第二个示例:当您将新对象传递给不窃取引用(创建新引用)的函数(如PySequence_SetItem ),但随后对其调用Py_DECREF时,引用计数将递增为2,并递减回1。因此,当元组最终被销毁并对其所有元素进行解引用时,引用计数将降至0。一切又好起来了。

如果你想知道为什么Python会同时使用非窃取函数,你只需要考虑一个不那么简单的例子。

如果您想将项目放在两个元组中而不是一个元组中,该怎么办?或者,如果你想把它放在一个元组中,但也要把它存储在一个C静态指针中,或者存储在某个模块的全局变量中,或者其他什么地方?如果你想把引用计数放在两个地方,你希望它增加2,当你的局部变量消失时,它们又减少了1。对于真正简单的情况,您只是创建一些东西并立即将其传递出去,引用窃取函数可以让您避免这种一步一个脚印的情况,而且对于一行代码也很好和方便。但对于更复杂的情况,这是没有意义的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51236885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档