template boy
template boy

Reputation: 10490

Segmentation fault from function call in destructor

Why does this code compile and correctly print "Derived"?

template <class Derived>
class Base
{
public:
    Base(Derived& d) : derived(d) {}
    void f() { std::cout << "Base\n"; }
    virtual ~Base() { derived.f(); }
private:
    Derived& derived;
};

class Derived : public Base<Derived>
{
public:
    Derived() : Base<Derived>(*this) {}
    void f() { std::cout << "Derived\n"; }
};

int main()
{
    Derived d;
}

But either making Base::f virtual or both Derived::f and Base::f virtual causes "Base" to be printed. Also, changing Derived::f to virtual gives a Invalid memory reference (SIGSEGV). I would expect those two other cases to print "Derived" since I'm calling it from a Derived instance.

Why does this happen?

Upvotes: 0

Views: 97

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126536

This is a dangling reference.

You initialize the field Base::derived to be a reference to the Derived object via the Derived constructor, but then you access it in the Base destructor after the Derived object has been destroyed.

Access any object after it has been destroyed (via either pointer or reference) is undefined behavior, so anything might happen.

Upvotes: 2

Related Questions