tags:

views:

800

answers:

6

I usually never see test for new in C++ and I was wondering why.

Foo *f = new Foo;

// f is assumed as allocated, why usually, nobody test the return of new?

+35  A: 

As per the current standard, new never returns NULL, it throws a std::bad_alloc instead. If you don't want new to throw(as per the old standard) but rather return NULL you should call it by postfixing it with "(std::nothrow)". i.e.

Foo* foo = new (std::nothrow) Foo;

Of course, if you have a very old or possibly broken toolchain it might not follow the standard.

David Holm
"It never returns NULL"... then you go ahead and contradict yourself :) using std::nothrow makes the first part of your statement false :)
OJ
It does not make it false, just a bit inconsistent. The "normal" verison of new never returns NULL.
Gorpik
It wouldn't hurt to fix the answer though!
Richard Corden
Edited the answer for clarity.
Paul Nathan
The MSVC <=2003 is a broken toolchain
osgx
A: 

Usually no one tests the return of new in new code because Visual Studio now throws the way the standard says.

In old code if a hack has been done to avoid throwing then you'd still better test.

Windows programmer
What about the question implied that the environment was MS DevStudio?
Chris Becke
Nothing. But if Visual Studio had not received this fix then the poster would be a lot less likely to be in this situation "I usually never see test for new in C++". So I explained it.
Windows programmer
+4  A: 

It all depends which version of C++ the code targets. The c++ specification for a long time now has stated that, by default at least, failures in new will cause a c++ exception, so any code performing a test would be entirely redundant. Most programming nowadays also targets virtual memory operating systems where its almost impossible to run out of memory, AND an out-of-memory condition is so fatal anyway that just letting the application crash on the next NULL access is as good a way of any of terminating.

Its only really in embedded programming, where exception handling is deemed to be too much of an overhead, and memory is very limited, that programmers bother to check for new failures.

Chris Becke
Catching the exception and saving data to disk, might be a better way than just letting the app crash...
Chris M.
But how? Modern c++ is full of object creation all over the place. When one "new" fails its strongly expected that further attempts to new will also fail. Which means an attempt to persist data to disk will also fail.
Chris Becke
"where its almost impossible to run out of memory" I disagree it is easy to run out of virtual memory on a 32 bit process - in windows you only get 2 Gig of address space - any domain involving sampled data - video, medical etc. can easily fill this up or fragment it leading to an allocation failure
morechilli
It all depends on your application domain. With large data sets, is it typcial to use STL type containers? Personally, when Im getting close to allocating enough memory to exhaust virtual memory space, im using a native allocator, which I would check for failure.
Chris Becke
@Chris Becke: "but how?". One way is to allocate a "big enough" block of memory upfront and register a new_handler which frees it and then throws bad_alloc. The application catches the exception, and there is now "enough" memory available for it to print diagnostics and exit cleanly.
Steve Jessop
Obviously the value of "enough" depends on the C++ implementation as well as on the application, so it may not be possible to gain absolute certainty, but you can typically do a lot better than just terminating due to an unhandled exception: at the very least you can ensure the stack is unwound.
Steve Jessop
+2  A: 

As quoted here

"In compilers conforming to the ISO C++ standard, if there is not enough memory for the allocation, the code throws an exception of type std::bad_alloc. All subsequent code is aborted until the error is handled in a try-catch block or the program exits abnormally. The program does not need to check the value of the pointer; if no exception was thrown, the allocation succeeded."

Burkhard
+3  A: 

It all depends on your complier VC++ up to version 6 gives NULL if the new operator fails, on a non MFC application.

Now the problem gets bigger when you use for example STL with VC++ 6, because the STL goes with the standards it will never test for NULL when he needs to get some memory, and guess what will happen under low memory conditions....

So for everybody that still uses VC++ 6 and STL check this article for a Fix. Don't Let Memory Allocation Failures Crash Your Legacy STL Application

João Augusto
+3  A: 
  1. new throws std::bad_alloc by default. If you use default, checking for null is obsolete, but handling exceptions is necessary. This default behavior is consistent with C++ exception safety paradigm - it usually provides that an object is either constructed or not allocated

  2. if you override default by using new (std::nothrow), checking on null is necessary. "New" both allocates and commits pages, so it is possible to run out of memory, either because you ran out of page descriptors, or because there's no physical memory available

  3. research your OS's memory management. C/C++ reference machine does not know how your OS manages memory, so relying on language alone is not safe. For example of memory allocation gone bad, read on C malloc() + Linux overcommit

n-alexander