What actually happens under the hood when a base class lacks a virtual destructor:
class Base {
public:
~Base() { std::cout << "~Base\n"; }
};
class Derived : public Base {
std::vector<int> m_buffer;
public:
~Derived() { std::cout << "~Derived\n"; }
};
Base* p = new Derived();
delete p; // UNDEFINED BEHAVIOR!Because ~Base() is non-virtual, the compiler performs static dispatch calling only Base::~Base(). The Derived destructor is never executed, leaking m_buffer's dynamic heap memory!