In Exceptional C++, Herb Sutter wrote in Item 35 as a guideline:
Prefer using the free store (new/delete). Avoid using the heap (malloc/free).
Why should I?
If an implementation chooses to implement new
by using malloc
, an overhead would probably incur, so that looks like a bad piece of advice as far as performance is concerned.
The new
and delete
keywords in C++ usually are implemented in terms of malloc
and free
, but they're designed to do different things.
In C++, if you say
new T(/* args */)
C++ will do the following:
T
.std::bad_alloc
object if no memory is available.T
in that block of memory.T
throws an exception.If you just use malloc
, you have to do all of these steps manually, which would be very, very hard. It might look something like this:
T* memory = nullptr;
while (true) {
memory = static_cast<T*>(malloc(sizeof(T)));
if (memory != nullptr) break;
std::get_new_handler()();
}
try {
new (memory) T(/* args */);
} catch (...) {
free(memory);
throw;
}
There are some other nuances here that I've glossed over (like calling operator new
instead of malloc
, or handling zero-sized requests, etc.), but I hope this helps explain how new
and malloc
are different.
So why should you use new
over malloc
? Well, there's a few reasons:
It's much safer. With malloc
you can forget to check the return type for a null pointer, or you could request the wrong amount of storage space, or you could forget to call the constructor on the object, or you could forget to deallocate memory if the constructor throws an exception, etc.
It's more type-safe. malloc
returns a void*
, which is just a pointer to a block of memory. Using malloc
, you have to cast the pointer to the proper type, which introduces the potential for errors later on.
It allows customization. Certain types overload operator new
to request memory in an unusual way, such as from a pooled allocator or from certain pieces of memory that might be faster, or using a custom allocator that optimizes over the usage pattern. Given this, you can automatically customize all times where memory is allocated dynamically for an object of type T
simply by defining operator new
and operator delete
. If you use malloc
, you have to chase down all memory allocation sites throughout the entire program.
That said, there are some advantages to malloc
. If you know for certain that you're allocating objects that are trivial objects (like primitives or structs that just hold data), it might be slightly faster to use malloc
. malloc
also lets you use realloc
, which free
doesn't. But honestly, you're probably better off just using std::vector
or std::array
in cases like this, since they're safer, easier to debug, and with good compiler support are likely to be aggressively optimized.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With