#include <cstdlib>
#include <cstdio>
#include <exception>


void* operator new(std::size_t n)
{
  std::puts("usual new");
  void* p = std::malloc(n);
  return p ? p : throw std::exception();
}
void operator delete(void* p)
{
  std::puts("usual delete1");
  std::free(p);
}

void* operator new(std::size_t n, std::size_t)
{
  std::puts("placement new");
  void* p = std::malloc(n);
  return p ? p : throw std::exception();
}
void operator delete(void* p, std::size_t)
{
  std::puts("usual delete2");
  std::free(p);
}

constexpr struct throwable_t {} throwable;
struct sth
{
  sth() = default;
  sth(const throwable_t&) { throw std::exception(); }
};

int main()
{
  std::puts("usual new/delete");
  sth* p = new sth();
  delete p;
 
  try { p = new sth(throwable); }
  catch (...) {}
 
  std::puts("placement new/delete");
  p = new (123) sth();
  p->~sth();
  operator delete(p, 123);
 
  try { p = new(123) sth(throwable); }
  catch (...) {}
}