Keil Logo

ARMCC: C++ operator new returns NULL on failure


Information in this knowledgebase article applies to:

  • Keil MDK 5
  • Arm Compiler 5

QUESTION

If the Heap memory is full, by default the following operator new call does not return NULL on such a failure, instead it throws an exception.

How can I get a NULL as a return value of the operator new-call instead, of an exception, when memory allocation fails?

ANSWER

There are two single-object allocation forms of operator new:

(1) void * operator new(std::size_t) throw (std::bad_alloc)
(2) void * operator new(std::size_t, std::nothrow_t&)) throw ()

which are invoked by calls of the forms:

(1) new T
(2) new(std::nothrow) T

respectively.

If either of these forms fails to obtain the required memory, they will call the current new_handler function if one is installed (function set_new_handler installs one) to make more memory available for allocation, and then they will retry. 

If the new_handler doesn't make memory available, it is allowed to call abort or exit, or to throw an exception of type std::bad_alloc or a type derived from it. 

Form (2) of operator new will catch this and return NULL, whereas form (1) will allow the exception to propagate outwards.

If no user-defined new_handler has been installed, which is the case by default, then on a failing allocation form (2) will return NULL and form (1) will throw std::bad_alloc.

Thus the possible outcomes of a form (1) new T call are: 

  • valid memory returned
  • call to abort or exit
  • throw of std::bad_alloc or a type derived from it.

The possible outcomes of a form (2) new(std::nothrow) T call are:

  • valid memory returned
  • call to abort or exit
  • NULL returned.

Our implementation of Arm Compiler 5 would behave like that if any source code was compiled with exceptions enabled. 

If all code was compiled with exceptions disabled, then a failed form (1) new will call std::terminate(). In other words, the effect is as if an exception was thrown but not caught. The default action of std::terminate is to call abort(), and in our library that calls__rt_SIGABRT().

Therefore, in order to get return value NULL on memory allocation failure, the operator new(std::nothrow) T should be used.

The compiler command-line option --force_new_nothrow can be used to fulfil this purpose for certain cases as well. However, it is not recommended to be used.

MORE INFORMATION

Last Reviewed: Thursday, November 5, 2020


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.