I've got a C++ class that has an attribute that is heap allocated and needs to be deleted when the object is destructed. The result of writing a wrapper class and trying to instantiate it is a double-free.
test.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;
};
module.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__")
After compiling, running the command python3 -c "import module; b = module.PyBar()" gives this output:
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)
I understand that the default constructor is called once when the PyBar object is declared, because cpp_bar is stack allocated, but why are there three Bars being constructed? And why is the third Bar being destructed at all, forget about twice?
