Why should I use a free store over a bunch?

In Exceptional C ++, Herb Sutter wrote in Point 35 as a guide:

Prefer to use the free store (new / delete). Avoid using heaps (TaNos / free).

Why should I?

If the implementation decides to implement new with malloc , there is likely to be overhead, so this seems like bad performance advice.

+4
source share
1 answer

The new and delete keywords in C ++ are usually implemented from the point of view of malloc and free , but they are intended for different actions.

In C ++, if you say

 new T(/* args */) 

C ++ will do the following:

  • Trying to allocate enough memory to store an object of type T
  • In case of failure, try to use the new handler for free space, eventually throwing out the std::bad_alloc object if there is no memory.
  • An attempt to construct an object of type T in this memory block.
  • Automatically free memory if building an object of type T throws an exception.

If you just use malloc , you need to complete all these steps manually, which would be very, very difficult. It might look something like this:

 T* memory; while (true) { memory = static_cast<T*>(malloc(sizeof(T))); if (memory == nullptr) std::get_new_handler()(); } try { new (memory) T(/* args */); } catch (...) { free(memory); throw; } 

There are some other nuances here that I have been silent about (for example, calling operator new instead of malloc or handling zero size requests, etc.), but I hope this helps to explain how new and malloc differ.

So why should you use new over malloc ? Well, there are several reasons:

  • It is much safer. malloc you may forget to check the return type for the null pointer, or you may request the wrong amount of storage space, or you may forget to call the constructor of the object, or you may forget to free memory if the constructor throws an exception, etc.

  • This is a safer type. malloc returns void* , which is just a pointer to a block of memory. Using malloc , you must direct the pointer to the appropriate type, which will later lead to errors.

  • It allows you to customize. Some types overload operator new to request memory in an unusual way, for example, from a merged allocator or from specific pieces of memory that can be faster, or using a custom allocator that optimizes the usage pattern. Given this, you can automatically tune all the time when memory is allocated dynamically for an object of type T , simply by defining operator new and operator delete . If you use malloc , you should pursue all memory allocation sites throughout the program.

However, there are some advantages to malloc . If you know for sure that you select objects that are trivial objects (for example, primitives or structures that just store data), it may be a little faster to use malloc . malloc also allows the use of realloc , which free does not support. But to be honest, you are probably best off using std::vector or std::array in such cases, since they are safer, easier to debug and with good compiler support, they are likely to be aggressively optimized.

Hope this helps!

+11
source

Source: https://habr.com/ru/post/1479406/


All Articles