Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Malloc vs New for Primitives

I understand the benefits of using new against malloc in C++. But for specific cases such as primitive data types (non array) - int, float etc., is it faster to use malloc than new?

Although, it is always advisable to use new even for primitives, if we are allocating an array so that we can use delete[].

But for non-array allocation, I think there wouldn't be any constructor call for int? Since, new operator allocates memory, checks if it's allocated and then calls the constructor. But just for primitives non-array heap allocation, is it better to use malloc than new?

Please advise.

like image 570
Rajeev Mehta Avatar asked Jun 16 '17 11:06

Rajeev Mehta


People also ask

Is malloc better than new?

new allocates memory and calls constructor for object initialization. But malloc() allocates memory and does not call constructor. Return type of new is exact data type while malloc() returns void*. new is faster than malloc() because an operator is always faster than a function.

Why should we use new instead of malloc?

malloc(): It is a C library function that can also be used in C++, while the “new” operator is specific for C++ only. Both malloc() and new are used to allocate the memory dynamically in heap. But “new” does call the constructor of a class whereas “malloc()” does not.

Which is faster new or malloc?

So, malloc is faster on average, but there's enough variation in speed (in both new and malloc ) that an individual invocation of new might actually be faster than an individual invocation of malloc .


1 Answers

Never use malloc in C++. Never use new unless you are implementing a low-level memory management primitive.

The recommendation is:

  • Ask yourself: "do I need dynamic memory allocation?". A lot of times you might not need it - prefer values to pointers and try to use the stack.

  • If you do need dynamic memory allocation, ask yourself "who will own the allocated memory/object?".

    • If you only need a single owner (which is very likely), you should use std::unique_ptr. It is a zero cost abstraction over new/delete. (A different deallocator can be specified.)

    • If you need shared ownership, you should use std::shared_ptr. This is not a zero cost abstraction, as it uses atomic operations and an extra "control block" to keep track of all the owners.


If you are dealing with arrays in particular, the Standard Library provides two powerful and safe abstractions that do not require any manual memory management:

  • std::array<T, N>: a fixed array of N elements of type T.

  • std::vector<T>: a resizable array of elements of type T.

std::array and std::vector should cover 99% of your "array needs".


One more important thing: the Standard Library provides the std::make_unique and std::make_shared which should always be used to create smart pointer instances. There are a few good reasons:

  • Shorter - no need to repeat the T (e.g. std::unique_ptr<T>{new T}), no need to use new.

  • More exception safe. They prevent a potential memory leak caused by the lack of a well-defined order of evaluation in function calls. E.g.

    f(std::shared_ptr<int>(new int(42)), g()) 

    Could be evaluated in this order:

    1. new int(42)
    2. g()
    3. ...

    If g() throws, the int is leaked.

  • More efficient (in terms of run-time speed). This only applies to std::make_shared - using it instead of std::shared_ptr directly allows the implementation to perform a single allocation both for the object and for the control block.

You can find more information in this question.

like image 143
Vittorio Romeo Avatar answered Sep 19 '22 06:09

Vittorio Romeo