【问题标题】:Is incrementing Py_True/Py_False refcount always necessary?是否总是需要增加 Py_True/Py_False 引用计数?
【发布时间】:2019-10-07 05:01:57
【问题描述】:

我是 Python C-API 的新手,我浏览了一些源代码来挑选其中的一部分。

这是我在包含扩展模块的包的 C 源代码中找到的函数的最小版本:

#define PY_SSIZE_T_CLEAN
#include <Python.h>

static PyObject *
modulename_myfunc(PyObject *self, PyObject *args) {

    // Call PyArg_ParseTuple, etc ...

    // Dummy values; in the real function they are calculated
    int is_found = 1;
    Py_ssize_t n_bytes_found = 1024;

    PyObject *result;
    result = Py_BuildValue("(Oi)",
                           is_found ? Py_True : Py_False,  // Py_INCREF?
                           n_bytes_found);
    return result;
}

这是否会因为未能在 Py_TruePy_False 上使用 Py_INCREF 而引入少量内存泄漏? C-API docs for Boolean object 似乎非常明确地表明总是需要增加/ decref Py_TruePy_False

如果确实需要引入Py_INCREF,假设Py_RETURN_TRUE/Py_RETURN_FALSE 由于返回元组而实际上并不适用,那么如何最恰当地使用它?

【问题讨论】:

    标签: python c python-3.x python-c-api


    【解决方案1】:

    这里没有使用Py_INCREF 的原因是因为Py_BuildValue,当被传递一个带有“O”的对象时会为你增加引用计数:

    O(对象)[PyObject *]

    传递一个未触及的 Python 对象(除了它的引用计数,它加一)。如果传入的对象是 NULL 指针,则假定这是因为产生参数的调用发现错误并设置了异常。因此, Py_BuildValue() 将返回 NULL 但不会引发异常。如果尚未引发异常,则设置 SystemError。

    例如,您将在 CPython itself 中看到类似的用法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-07
      • 2013-03-08
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 2016-11-29
      相关资源
      最近更新 更多