首页 > 解决方案 > Cython 何时调用 C++ 析构函数?

问题描述

delete我有一个 C++ 类,它的属性是堆分配的,当对象被破坏时需要d 。编写包装类并尝试实例化它的结果是双重释放。

测试.h

#include <iostream>

int barIdCounter = 0;

class Foo
{
public:
    Foo() {}
    Foo(int x): x(x) {}
private:
    int x;
};

class Bar
{
public:
    Bar()
    {
        id = barIdCounter;
        barIdCounter++;
        std::cout << "constructing Bar " << id << std::endl;
        foo = new Foo(1);
    }

    ~Bar()
    {
        std::cout << "destructing Bar " << id << std::endl;
        delete foo;
    }

    Foo* getFoo() const {return foo;}
    int getId() const {return id;}
private:
    Foo* foo;
    int id;
};

模块.pyx

# distutils: language = c++
# cython: language_level = 3

cdef extern from "test.h":
    cdef cppclass Foo:
        pass

    cdef cppclass Bar:
        Bar() except +
        Foo* getFoo()
        int getId()


cdef class PyBar:

    cdef Bar cpp_bar

    def __cinit__(self):
        print("beginning PyBar.__cinit__")
        self.cpp_bar = Bar()
        print(f"self.cpp_bar has id {self.cpp_bar.getId()}")
        print("exiting PyBar.__cinit__")

编译后,运行命令python3 -c "import module; b = module.PyBar()"会给出以下输出:

constructing Bar 0
constructing Bar 1
beginning PyBar.__cinit__
constructing Bar 2
destructing Bar 2
self.cpp_bar has id 2
exiting PyBar.__cinit__
destructing Bar 2
free(): double free detected in tcache 2
Aborted (core dumped)

我知道在PyBar声明对象时调用了一次默认构造函数,因为cpp_bar分配了堆栈,但是为什么Bar要构造三个s?为什么第三个Bar被破坏了,忘记了两次?

标签: c++cython

解决方案


推荐阅读