gpt4 book ai didi

python - 为什么在 C 中返回 Py_None 之前需要 Py_INCREF(Py_None)?

转载 作者:IT老高 更新时间:2023-10-28 22:21:21 28 4
gpt4 key购买 nike

为什么在 C 中返回 Py_None 之前需要 Py_INCREF(Py_None),如下所示?

Py_INCREF(Py_None);
return Py_None;

如果省略 Py_INCREF(Py_None),会发生什么?

最佳答案

缺少 Py_INCREF 将导致对 Py_None 的引用计数不正确,这可能导致解释器释放 Py_None。由于 Py_None 是在 Objects/object.c 文件中静态分配的:

PyObject _Py_NoneStruct = {
_PyObject_EXTRA_INIT
1, &PyNone_Type
};

并且在 Include/object.h 中有定义:

#define Py_None (&_Py_NoneStruct)

那么会发生什么,解释器会因 fatal error 而崩溃:

Fatal Python error: deallocating None

Objects/object.c中的none_dealloc函数生成:

/* ARGUSED */
static void
none_dealloc(PyObject* ignore)
{
/* This should never get called, but we also don't want to SEGV if
* we accidentally decref None out of existence.
*/
Py_FatalError("deallocating None");
}

正如该评论所述,如果 NoneType 没有自己的解除分配功能,您将获得段错误,因为 free 调用将在堆栈。

您可以复制 tutorial 中的示例进行测试。 ,在 Noddy_name 函数中添加对 Py_DECREF(Py_None) 的调用,构建扩展并执行循环调用该方法。


在一般情况下,0 的引用计数会导致程序以多种不同方式失败。

特别是 python 可以自由地重用被释放的对象使用的内存,这意味着突然对对象的每个引用都可以成为对随机对象(或空内存位置)的引用,并且您可以看到类似的东西:

>>> None   #or whatever object that was deallocated
<ARandomObjectYouNeverSawBefore object at ...>

(对我来说,这实际上是 happened,有时在编写 C 扩展时。由于缺少对 Py_INCREF 的调用,某些对象会随机变为只读缓冲区)。

在其他情况下,可能会引发不同类型的错误,或者解释器可能会崩溃或段错误。

关于python - 为什么在 C 中返回 Py_None 之前需要 Py_INCREF(Py_None)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15287590/

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