[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