PyCapsule\u New失败时的指针所有权

2024-06-08 16:56:31 发布

您现在位置:Python中文网/ 问答频道 /正文

PyCapsule_New接受析构函数,当胶囊被销毁时调用:

PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)

我试图使用这个机制来把C++代码创建的对象的所有权传递给Python。具体地说,析构函数只是对对象调用“delete”。在

^{pr2}$

在我看来,这里有一个潜在的内存泄漏:如果PyCapsule-New失败,则释放的原始指针将悬空。我试图从pythoncapi文档中得到确认。但是,它只提到在失败时,会设置一个异常,并返回NULL。它不是说所有权。在

假设指针悬空似乎是合理的,因为如果胶囊不是首先生成的,那么就没有传递给析构函数的处理程序。在

但是,我不确定PyCapsule_New是否在内部调用析构函数,特别是:

  • 在PyCapsule-New内部,胶囊结构几乎完成。在
  • 失败就在它回来之前发生。在
  • PyCapsule\u New设置一个异常,在调用析构函数(???)后返回NULL

如果突出显示的部分永远不会发生,在我看来,上面的代码将不得不重新编写为

auto ptr = make_unique<ObjType>(arg);
PyObject * ret = PyCapsule_New(ptr.get(), nullptr, Destroyer);
if (ret != nullptr)
    ptr.release();

有人能帮我确认一下是不是真的吗?在


Tags: 对象函数代码newnullpyobjectret指针
1条回答
网友
1楼 · 发布于 2024-06-08 16:56:31

按照建议,将评论改为答案。在

简单回答:不,当PyCapsule-New失败时,它不叫驱逐舰。在

参见https://github.com/python/cpython/blob/master/Objects/capsule.c#L44中的实现

PyObject *
PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
{
    PyCapsule *capsule;

    if (!pointer) {
        PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
        return NULL;
    }

    capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
    if (capsule == NULL) {
        return NULL;
    }

    capsule->pointer = pointer;
    capsule->name = name;
    capsule->context = NULL;
    capsule->destructor = destructor;

    return (PyObject *)capsule;
}

因此,第一个实现确实包含潜在的内存泄漏。”release()”只应在PyCapsule\u New成功时调用。在

相关问题 更多 >