问题描述
我注意到 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++ 中,使用动态内存构造对象包括两个步骤:
- 为对象分配内存。
- 使用有效的构造函数初始化对象。
另一方面,使用动态内存销毁对象也涉及两个步骤:
- 调用析构函数来销毁对象。
- 为对象释放内存。
从您的帖子中不清楚您是如何构建对象的,但破坏的问题很明显。您有第 2 步的代码,但没有第 1 步的代码。
在我看到您构建对象的代码之前,我不想提出正确处理对象销毁的具体方法。