Can the new
operator throw an exception in real life?
And if so, do I have any options for handling such an exception apart from killing my application?
Update:
Do any real-world, new
-heavy applications check for failure and recover when there is no memory?
In many cases there's no reasonable recovery for an out of memory situation, in which case it's probably perfectly reasonable to let the application terminate. You might want to catch the exception at a high level to display a nicer error message than the compiler might give by default, but you might have to play some tricks to get even that to work (since the process is likely to be very low on resources at that point).
Unless you have a special situation that can be handled and recovered, there's probably no reason to spend a lot of effort trying to handle the exception.
It depends on the compiler/runtime and on the
operator new
that you are using (e.g. certain versions of Visual Studio will not throw out of the box, but would rather return aNULL
pointer a lamalloc
instead.)You can always
catch
astd::bad_alloc
exception, or explicitly usenothrow new
to returnNULL
instead of throwing. (Also see past StackOverflow posts revolving around the subject.)Note that
operator new
, likemalloc
, will fail when you have run out of memory, out of address space (e.g. 2-3GB in a 32-bit process depending on the OS), out of quota (ulimit
was already mentioned) or out of contiguous address space (e.g. fragmented heap.)Note that in Windows, very large new/mallocs will just allocate from virtual memory. In practice, your machine will crash before you see that exception.
Try it if you dare!
osgx said:
I have answered this previously in my answer to this question, which is quoted below:
I use Mac OS X, and I've never seen
malloc
returnNULL
(which would imply an exception fromnew
in C++). The machine bogs down, does its best to allocate dwindling memory to processes, and finally sends SIGSTOP and invites the user to kill processes rather than have them deal with allocation failure.However, that's just one platform. CERTAINLY there are platforms where the default allocator does throw. And, as Chris says,
ulimit
may introduce an artificial constraint so that an exception would be the expected behavior.Also, there are allocators besides the default one/
malloc
. If a class overridesoperator new
, you use custom arguments tonew(…)
, or you pass an allocator object into a container, it probably defines its own conditions to throwbad_alloc
.The new-handler function is the function called by allocation functions whenever new attempt to allocate the memory fails. We can have our own logging or some special action, eg,g arranging for more memory etc. Its intended purpose is one of three things: 1) make more memory available 2) terminate the program (e.g. by calling std::terminate) 3) throw exception of type std::bad_alloc or derived from std::bad_alloc. The default implementation throws std::bad_alloc. The user can have his own new-handler, which may offer behavior different than the default one. THis should be use only when you really need. See the example for more clarification and default behaviour,