...
In this example, array
is copied into dynamically allocated memory referenced by copy
. However, the result of malloc()
is not checked before copy
is referenced. Consequently, if malloc()
fails, the program abnormally terminates.
Code Block | ||||
---|---|---|---|---|
| ||||
void f(const int *array, std::size_t size) { int* copy = (int*)std::malloc(size * sizeof *copy); std::memcpy(copy, array, size * sizeof *copy); // ... free(copy); } |
...
This example remains noncompliant if we replace malloc()
with new(std::nothrow)
.
Code Block | ||||
---|---|---|---|---|
| ||||
void f(const int* array, std::size_t size) { int* copy = new(std::nothrow) int[size]; std::memcpy(copy, array, size * sizeof *copy); // ... delete[] copy; } |
...
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 | ||||
---|---|---|---|---|
| ||||
int f(const int* array, std::size_t size) { int* const copy = new(std::nothrow) int[size]; if (copy == NULL) { // Indicate error to caller. return -1; } std::memcpy(copy, array, size * sizeof *copy); // ... delete[] copy; // Indicate successful completion. return 0; } |
...
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 | ||||
---|---|---|---|---|
| ||||
int f(const int* array, std::size_t size) { int* copy; try { copy = new int[size]; } catch (std::bad_alloc&) { // Indicate error to caller. return -1; } std::memcpy(copy, array, size * sizeof *copy); // ... delete[] copy; // Indicate successful completion. return 0; } |
...