I've seen lots of people in my team checking null pointers like this:
SomeClass *pSc = new SomeClass;
if ( NULL == pSc )
{
// cope with error
}
I known this will not work, because new operator in c++ throws a std::bad_alloc exception instead of returning NULL. I also know that std::nothrow can make what they expected really happen. So I wrote an example like this:
#include <iostream>
#include <limits>
#include <new>
using namespace std;
void myNewHandler()
{
std::cerr << "Failed to allocate memory!" << std::endl;
}
int main(int argc, char* argv[])
{
//std::new_handler oldHandler = std::set_new_handler(myNewHandler);
int *pLotsMem = new(std::nothrow) int[std::numeric_limits<long long>::max()];
if ( nullptr == pLotsMem )
{
std::cerr << "Allocation failed" << std::endl;
return -1;
}
else
{
delete[] pLotsMem;
pLotsMem = nullptr;
}
//std::set_new_handler(oldHandler);
return 0;
}
Yes, I wanted to demonstrate usage of std::set_new_handler as well. To my surprise, even this did not work. new operator still threw an exception(std::bad_array_new_length, a derived class of std::bad_alloc) and then terminated the program.
Any idea why this failed to work? How should one check pointers returned by new operator in gcc?
Believe or not, this is standard compliant behavior:
In short, non-throwing allocator function is not even called, exception is thrown by new-expression itself.
I assume that you are not using modern C++ version, because in those
std::numeric_limits<long long>::max()
marked asconstexpr
and is a core constant expression, which yields compile-time error.Clang, probably has implementation-defined limit set higher than max value of long lond, bypassing this quirk of C++.