Python 对象中的 C++ 对象包装器未销毁

问题描述

我注意到 Python 对象中包裹的 C++ 对象在 Python 对象释放时并没有被销毁。

这是我使用 cpython C API 的类型定义:

typedef struct {
    PyObject_HEAD
    CppFoo fooObj;
    std::vector<Py_ssize_t> size;
} FooObject;

这是 tp_dealloc:

void FooObject_dealloc(FooObject* self) {
    Py_TYPE(self)->tp_free((PyObject*)self);
}

在 Python 中调用以下代码时,会在调试器中命中 FooObject_dealloc:

>>>myfoo=Foo()
>>>del myfoo

然而,即使在 tp_init 中调用了构造函数,也没有调用 CppFoo 的析构函数。这怎么会发生? CppFoo 的析构函数不应该在 myfoo 被释放时自动调用吗?应该怎么做才能避免fooObj的泄露?

编辑: 我几乎遵循了创建类型的教程:

https://docs.python.org/3/extending/newtypes_tutorial.html

不同的是,我在 PyObject_HEAD 之后将 C++ 对象添加到了 int 或 PyObject* 以外的类型中。

解决方法

在 C++ 中,使用动态内存构造对象包括两个步骤:

  1. 为对象分配内存。
  2. 使用有效的构造函数初始化对象。

另一方面,使用动态内存销毁对象也涉及两个步骤:

  1. 调用析构函数来销毁对象。
  2. 为对象释放内存。

从您的帖子中不清楚您是如何构建对象的,但破坏的问题很明显。您有第 2 步的代码,但没有第 1 步的代码。

在我看到您构建对象的代码之前,我不想提出正确处理对象销毁的具体方法。