#include <iostream>
#include <cstddef>

class Base_no_virt_dtor {
  int a[10];
};

class Derived_no_virt_dtor : public Base_no_virt_dtor {
  int b[10];
};

class Base_virt_dtor {
  int c[10];
public:
  virtual ~Base_virt_dtor() = default;
};

class Derived_virt_dtor : public Base_virt_dtor {
  int d[10];
};

// replaceable usual deallocation functions
// (since C++14)
void operator delete  ( void* ptr, std::size_t sz ) noexcept{
  std::cout << "delete (ptr=" << ptr << ", sz=" << sz << ");\n";
}

int main(void) {
  std::cout << "sizeof(Base_no_virt_dtor) = " << sizeof(Base_no_virt_dtor) << ";\n";
  std::cout << "sizeof(Derived_no_virt_dtor) = " << sizeof(Derived_no_virt_dtor) << ";\n";
  std::cout << "sizeof(Base_virt_dtor) = " << sizeof(Base_virt_dtor) << ";\n";
  std::cout << "sizeof(Derived_virt_dtor) = " << sizeof(Derived_virt_dtor) << ";\n";
  
  std::cout << std::endl;
  
  {
    Base_no_virt_dtor* baseptr_no_virt_dtor = new Derived_no_virt_dtor;
    std::cout << "baseptr_no_virt_dtor = " << baseptr_no_virt_dtor << ";\n";
    delete baseptr_no_virt_dtor;
  }
  
  std::cout << std::endl;
  
  {
    Base_virt_dtor* baseptr_virt_dtor = new Derived_virt_dtor;
    std::cout << "baseptr_virt_dtor = " << baseptr_virt_dtor << ";\n";
    delete baseptr_virt_dtor;
  }
  return 0;
}