...
By default operator new
will throw a std::bad_alloc
exception if the allocation fails. Therefore you need not check that the result of operator new
is NULL
. However, to ease conversion of code to C++, the C++ Standard ISO/IEC 14882-2003 provides a variant of operator new
that behaves like malloc()
:
Code Block |
---|
charint* s = new charint[-1]; // throws a std::bad_alloc exception charint* s = new (std::nothrow) charint[-1]; // returns NULL |
When using std::nothrow
, it is imperative to check that the return value is not NULL
before using it.
Noncompliant Code Example (malloc()
)
In this example, input_string
array
is copied into dynamically allocated memory referenced by str
copy
. However, the result of malloc()
is not checked before str
copy
is referenced. Consequently, if malloc()
fails, the program abnormally terminates.
Code Block | ||
---|---|---|
| ||
charint *input_stringarray; size_t size; /* initialize input_string array and size */ size_t size = strlen(input_string) + 1; charint *strcopy = (char *)malloc(size * sizeof(int)); strcpy(str, input_stringmemcpy( copy, array, size * sizeof(int)); /* ... */ free(strcopy); strcopy = NULL; |
Noncompliant Code Example (std::nothrow
)
This example remains noncompliant if we replace malloc()
with new(std::nothrow)
.
Code Block | ||
---|---|---|
| ||
charint *input_stringarray; size_t size; /* initialize input_string array and size */ size_t size = strlen(input_string) + 1; char *strint *copy = new(std::nothrow) charint[size]; strcpy(str, input_stringmemcpy( copy, array, size * sizeof(int)); /* ... */ delete[] strfree(copy); strcopy = NULL; |
Compliant Solution (std::nothrow
)
With std::nothrow
, the new operator returns either a null pointer or a pointer to the allocated space. Always test the returned pointer to ensure it is not NULL before referencing the pointer. Handle the error condition appropriately when the returned pointer is NULL.
Code Block | ||
---|---|---|
| ||
charint *input_stringarray; size_t size; /* initialize input_string array and size */ size_t size = strlen(input_string) + 1; charint *strcopy = new(std::nothrow) charint[size]; if (strcopy == NULL) { /* Handle allocation error */ } else { strcpy(str, input_stringmemcpy( copy, array, size * sizeof(int)); /* ... */ delete[] strfree(copy); strcopy = NULL; } |
Compliant Solution (bad_alloc
)
Alternatively, one can use operator new
without std::nothrow
. Unless std::nothrow
is provided, operator new
never returns NULL
; it will instead throw a std::bad_alloc
exception if it cannot allocate memory.
Code Block | ||
---|---|---|
| ||
charint *input_stringarray; size_t size; /* initialize input_string array and size */ size_t size = strlen(input_string) + 1; char *strint *copy = new charint[size]; strcpy(str, input_stringmemcpy( copy, array, size * sizeof(int)); /* ... */ delete[] strfree(copy); strcopy = NULL; |
Risk Assessment
Failing to detect allocation failures can lead to abnormal program termination and denial-of-service attacks.
...