29

According to C++ reference, you can new an object by:

MyClass * p1 = new MyClass;

or by

MyClass * p2 = new (std::nothrow) MyClass;

The second one will return a null pointer instead of throwing an exception.

However, I hardly see this version in my experience.

For example Google does not recommend using exception in their code, but they are not using the nothrow version either in Chromium as I can see.

Is there any reason that we prefer the default one against the nothrow one? Even in a project that is not using exception?

-- EDIT --

Follow up question: should I check return value of malloc()?

It looks like, on the contrary, many people advice to check return value of malloc, some said because:

many allocation failures have nothing to do with being out of memory. Fragmentation can cause an allocation to fail because there's not enough contiguous space available even though there's plenty of memory free.

Is this true? Why we treat malloc() and new() differently in this case?

Deqing
  • 14,098
  • 15
  • 84
  • 131
  • If new fails you are most likely out of memory and need to exit anyway... – Kelm Aug 05 '13 at 15:22
  • 1
    Note that in other languages, such as java - we distinguish between an *exception* and an *error* (which is *usually* fatal). In java, out of memory is an *error* and NOT an *exception*. – amit Aug 05 '13 at 15:26
  • 1
    Apart from asking opinion, your closing question seems contradictory. By-definition if you use the exception-throwing version, you're using exceptions, thereby making the point of "Even in a project that is not using exceptions" somewhat moot. If by "not using an exceptions" you mean you have no try-catch-blocks and therefore the runtime will catch the exception and terminate the program (usually) you're *stll* using exceptions; you're just not *handling* them in your authored code. – WhozCraig Aug 05 '13 at 15:27
  • 2
    Related, for everyone saying "you can't recover anyway, so why bother": [Is “Out Of Memory” A Recoverable Error?](http://stackoverflow.com/q/333736/395760) –  Aug 05 '13 at 15:27
  • @WhozCraig you aren't necessarily using exceptions just because you don't specify std::nothrow. You can also disable them with a compiler switch. – divegeek Apr 28 '17 at 12:36

2 Answers2

47

However, I hardly see this version in my experience.

You would use it (or, equivalently, catch the exception from the default version) if you can handle the failure locally; perhaps by requesting to free some other memory and then retrying, or by trying to allocate something smaller, or using an alternative algorithm that doesn't need extra memory.

Is there any reason that we prefer the default one against the nothrow one?

The general principle of exceptions: if you can't handle it locally, then there's no point in checking locally. Unlike return values, exceptions can't be ignored, so there's no possibility of ploughing on regardless and using a null pointer.

Even in a project that is not using exception?

Often, an out-of-memory condition can't be handled at all. In that case, terminating the program is probably the best response; and that is the default response to an unhandled exception. So, even if you're not using exceptions, the default new is probably the best option in most situations.

should I check return value of malloc()?

Yes: that's the only way to check whether it succeeded. If you don't, then you could end up using a null pointer, giving undefined behaviour: often a crash, but perhaps data corruption or other bizarre behaviour and long debugging sessions to (hopefully) figure out what went wrong.

Why we treat malloc() and new differently in this case?

Because malloc forces us to check the return value, while new gives us the option of less intrusive error handling.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
10

If you use the throwing version you don't need to test the result of every new call to see if it succeeded or failed. Typically speaking in many/most applications if your allocation fails you can't do much and just exit/abort, which the exception does for you automatically if you don't explicitly try/catch.

If you use the nothrow version you might wind up propagating a null pointer through your application and crashing/exiting MUCH later on at a point apparently totally unrelated to memory allocation, making debugging much harder.

Mark B
  • 95,107
  • 10
  • 109
  • 188