Why this code snippet ouputs a lot of "here"?
I think the program should terminate when after throw std::invalid_argument( "fool" );
has been called.
#include <memory>
#include <iostream>
void* operator new(std::size_t size)
{
std::cout << "here" << std::endl;
throw std::invalid_argument( "fool" ); //commit out this, there would be many many ouputs
return std::malloc(size);
}
void operator delete(void* ptr)
{
return free(ptr);
}
int main()
{
//std::unique_ptr<int> point2int(new int(999));
int* rawpoint2int = new int(666);
}
CodePudding user response:
The documentation for std::invalid_argument
holds the clue:
Because copying
std::invalid_argument
is not permitted to throw exceptions, this message is typically stored internally as a separately-allocated reference-counted string. This is also why there is no constructor takingstd::string&&
: it would have to copy the content anyway.
You can see that the string argument is copied by design. This means that re-entering new
is pretty much guaranteed if you are throwing this exception in this way.
You should also be aware that malloc
can return nullptr
which will violate the design of operator new
which should either return a valid pointer or throw.
The normal kind of exception to throw in this case is std::bad_alloc
. I cannot imagine why you are wanting to throw std::invalid_argument
. I thought perhaps you were encountering this issue in a constructor somewhere and decided to test the allocation itself.
Technically you can resolve the problem by passing a default-constructed string as the argument:
// ... but, why would you do this?!! :(
throw std::invalid_argument(std::string()); // will not allocate
Eww, yucky. I recommend you find a more appropriate exception to throw (if you actually need one), or create your own non-allocating exception.