C++, new vs malloc return value

Viewed 363

When I learnt C99 I was told to Always check the return value of malloc to check whether it succeeded or failed, but now I started learning C++ and I was told that there is no need to do this with the keyword new, and you can suppose that it will always work for you.

But why is that?

5 Answers

new can still fail and throw an std::bad_alloc exception, and your program needs to may check whether it did, or simply let the exception propagate up. There is also a flag you can pass to new to make it act like malloc and return NULL on error. Take a look at the documentation.


Edit Here are two examples:

try {
  char* arr = new char[20];
} catch (std::bad_alloc& e) {
  // Handle error
}

Or using the nothrow flag, making new act like malloc:

char* arr = new (std::nothrow) char[20];
if (!arr) {
  // Handle error
}

Any dynamic allocation can fail.

malloc signals this by returning NULL. If it failed, unless explicitly you check for its return the program will continue, even though malloc failed, most likely resulting in Undefined Behavior when you try to access via the pointer returned by malloc (which is NULL). This is why you should always check for malloc failure.

new on the other hand signals this by throwing an std::bad_alloc exception (default behavior). If you don't catch the the exception it will bubble up to the top and terminate your program. This is desired, so you don't need to do anything.


Also please note that in C++ you should never explicitly call new/delete. Use standard containers like std::vector or smart pointers.

New allocates memory and calls constructor for object initialization: if it fails it throws an exception std::bad_alloc. malloc allocates memory and does not call constructor: if its allocation fails, it return a null pointer, so you have to check what you get from it. However, in c++ you cannot assume that new will always work: you can assume that if it doesn't work, it throws an exception.

There are many ways to check the return values,

  • you could check the returned pointer if you use the nothrow version
  • you can use a try block on a much higher level
  • you can use the set_new_handler to check handle it for all new's.

I prefer the 2nd and 3rd.

In C++, unless you use advanced features, if memory cannot be allocated with the new operator, an exception is thrown, so the there is no need to check if the pointer obtained by new is null or not. Handling the exception is up to the programmer. If you don't, the program will terminate abruptly. It is actually tricky to handle this exception properly and restart the operations without memory or resource leaks, which is why allocation of objects with new and delete is now considered obsolete. Using containers and smart pointers is a better alternative.

Note that you can get the same behavior in C with a wrapper on malloc():

#include <stdio.h>
#include <stdlib.h>

void *xmalloc(size_t size) {
    void *p = malloc(size);
    if (p == NULL) {
        fprintf(stderr, "malloc failed for %zu bytes\n", size);
        exit(1);
    }
    return p;
}

There is no need to check for memory allocation failure by xmalloc() since such a failure causes an abrupt program termination automatically. This approach can be used for command line utilities where failure is not catastrophic and can be handled interactively.

Related