Search code examples
c++new-operatordynamic-memory-allocationdelete-operator

Why deallocation function is not called when object constructor throw in a new expression?


If I define operator delete as following and if an object constructor throw in the new expression I expected to see the result of the call to the defined operator delete:

#include <new>
#include <cstdlib>
#include <iostream>

void*
operator new(std::size_t s){
  std::cout << "alloc " << std::endl;
return std::malloc(s);
}

void
operator delete(void* p) noexcept {
  std::cout << "dealloc " << std::endl;
  std::free(p);
}
void
operator delete(void* p,std::size_t) noexcept{
    std::free(p);
    std::cout << "dealloc s" << std::endl;
}

struct A{
  A(int i){
     if(i>0)
       throw 10;
  }
};

int main(int argc// will equal 10
        ,char* arg[])
{
  for(int i=0;i<argc;++i)
     auto p=new A{argc};
  return 0;
}

This program just output alloc, why the operator delete are not called? In the standard [expr.new] it is specified that:

If any part of the object initialization described above terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed, after which the exception continues to propagate in the context of the new-expression.


Solution

  • If you fix your code to throw exception, it works as expected:

    int main(int argc,char* arg[])
    {
        try {
            new A(2);
        }
        catch (...)
        {}
    }
    

    Demo