[Exceptional C++ Style] Item 22: To new, Perchance to throw, Part 2: Pragmatic Issues in Memory Management

Jez Higgins jez at jezuk.co.uk
Wed Jan 19 17:11:19 EST 2005


Most forms of new report failure by throwing a bad_alloc exception.  The 
nothrow new reports a failure by return a null pointer, it wouldn't 
fulfil its guarantee otherwise.  (In-place new cannot fail.)

Given we have these two failure modes, is one "better" than the other. 
Specifically, does using the nothrow form of new help make code more 
exception-safe?

To a program that checks for new failing, the difference is merely 
syntactic.  Neither variety of new offers any more information than the 
other, so the error recovery will be the same in either case (assuming 
it is itself correct, of course).  The answer in this case, then, is no, 
it makes no difference.

To a program that doesn't check for new failing, nothrow new actually 
makes a program less exception-safe.  An uncaught bad_alloc will halt 
the program, but there will at least be some attempt to unwind the 
stack.  As things unwind, the objects destroyed on the way can release 
their resources, save state or whatever.  Dereferencing a null pointer, 
on the other hand, will cause a much more abrupt and unhealthy halt.

This leads us to moral #1 : Avoid nothrow new

The nothrow form of new has no inherent benefit and is, usually, words 
than the exception throwing alternative.  In either case though, 
recovery is difficult.

Moral #2 : There's often no point in checking for new failure anyway.

Shock!  Horrors!  Error-checking is next to Godliness!  etc, etc.

Let's temper our saintly impulses with a practicality.  Many systems 
allocate memory on an optimistic basis, and don't commit it until the 
memory is actually used.  Memory allocation on such systems (eg Linux) 
always succeeds, although, rather unfortunately, any subsequent memory 
write may fail.  It's not conformant, but it's life.

In these modern times, new rarely fails anyway.  Virtual memory systems 
are much more likely to start swapping themselves into oblivion long 
before memory is exhausted.  As the system grinds down the sysadmin (or 
even the humble programmer at his desktop) is likely to intervene and 
start killing things.

Finally, even if you do detect a new failure, there's probably not much 
you can do about it anyway.  Recovering from memory exhausting sensibly 
is difficult - one of our most basic resources has run out after all - 
and unwinding the stack is generally the best option.

---

It seems to me that nobody's going to change their programming practice 
after reading this item, and it simply serves to justify normal 
practice.  (A rare example of normal practice being good practice, 
perhaps?)  I've never seen a program that attempted to recover from new 
failing, nor one that used the nothrow form of new.  I strongly suspect 
that the same is true for the vast majority of us.

Obviously there are special cases - safety critical systems, for 
instance.  Systems like these need to do more than just catch 
bad_allocs, though.



--- StripMime Report -- processed MIME parts ---
multipart/signed
  text/plain (text body -- kept)
  application/pgp-signature
---



More information about the Effective-cpp mailing list