If the system is low on memory, new could fail and throw an exception
(the default behaviour). This would require a try/catch block to handle
the failure, otherwise the program would abort.

new could also be configured to return NULL, requiring an entirely
different error handling strategy.

It is generally inadvisable to mix memory allocated with new with memory
allocated using malloc() (as they could potentially be allocated in
different heap areanas, and cause corruption).

Modern Memory Management

To drastically simplify memory management and reduce the potential for bugs,
C++11 introduces several types of smart pointers:

std::unique_ptr: a pointer which is automatically freed when the pointer
goes out of scope, and has a single owner at all times

std::shared_ptr: a reference-counting pointer which can be shared among
multiple threads, and deletes the object when the last reference is released

std::weak_ptr: a handle which does not hold a reference, but can be
materialised into a std::shared_ptr on demand

These three smart pointer types should be able to cover the vast majority of
memory management needs in a typcail application. (There will always be
exceptions which need custom allocation strategies, such as high performance
games, numerical processing, etc).

By using the correct smart pointer according to the desired semantics, you
can virtually eliminate leaks and other common memory problems.