gpt4 book ai didi

Python C 扩展 : Py_DECREF for PyList

转载 作者:行者123 更新时间:2023-11-30 14:51:13 25 4
gpt4 key购买 nike

我有一个关于如何在 C 中的 PyList 上正确使用 Py_DECREF() 的问题。假设我有一个名为 build_list() 的函数,它接受链接的字符串list 作为其输入参数,如果一切顺利,则返回一个 Python 列表,如果出现错误,则返回 NULL

下面是一个简单的例子:

struct strlist {
char *str;
size_t len;
struct strlist *next;
};

PyObject *build_list (struct strlist *inlist) {
struct strlist *node = NULL;
PyObject *tmp_obj = NULL;
int success;

PyObject *ret_obj = PyList_New(0);
if (ret_obj == NULL) {
return NULL;
}

node = inlist;
while (node != NULL) {
tmp_obj = PyString_FromStringAndSize(node->str, node->len);
if (tmp_obj == NULL) {
Py_DECREF(ret_obj);
return NULL;
}
else {
success = PyList_Append(ret_obj, tmp_obj);
Py_DECREF(tmp_obj);
if (success != 0) {
Py_DECREF(ret_obj);
return NULL;
}
}
node = node->next;
}
return ret_obj;
}

在这种情况下我是否正确使用了 Py_DECREF()

我的具体问题是:如果在发生错误之前已将一些元素附加到列表中,我的代码将直接减少对列表的引用(在 success != 0 内),而列表中的元素从技术上讲仍然具有 refcount 1. 在最终减少对列表的引用之前,我是否应该先减少每个元素的引用?

谢谢。

最佳答案

创建list后,它的引用计数为 1。每个 string天生的引用计数为 1,将其附加到列表中会将其增加到 2(因为 list 和您的函数引用它)。所以 DECREF 是正确的Append()之后,因为您的函数不再使用 string本身。在两个错误路径( tmp_obj == NULLsuccess != 0 )内, DECREF荷兰国际集团list -object 将释放该对象(因为它的引用计数现在为 0)。 list -object 将遍历它的成员和 DECREF其中每一个,减少每个 string 的引用计数到 0,释放它们。

长话短说:您的代码是正确的。列表中的元素必须具有(至少)1 的引用计数,因为列表正在引用它们。这是list的独家责任DECREF这是成员(member)。

作为练习,您可以尝试自己减少字符串的引用计数。解释器很可能会崩溃(可能在 exit() 处),因为当列表被释放时,字符串的引用计数变为 -1,从而触发断言。

关于Python C 扩展 : Py_DECREF for PyList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48471726/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com