Why should would one replace the default operator new
and delete
with a custom new
and delete
operators?
This is in continuation of Overloading new and delete in the immensely illuminating C++ FAQ:
Operator overloading.
An followup entry to this FAQ is:
How should I write ISO C++ standard conformant custom new
and delete
operators?
These operators allocate memory for objects from a pool called the free store (also known as the heap). The new operator calls the special function operator new , and the delete operator calls the special function operator delete .
C++ language also supports these functions from the C language to allocate/de-allocate memory. Apart from these functions, C++ introduces two new operators which are more efficient to manage the dynamic memory. These are 'new' operator for allocating memory and 'delete' operator for de-allocating memory.
The delete operator removes a given property from an object. On successful deletion, it will return true , else false will be returned. However, it is important to consider the following scenarios: If the property which you are trying to delete does not exist, delete will not have any effect and will return true .
New and Delete operators can be overloaded globally or they can be overloaded for specific classes. If these operators are overloaded using member function for a class, it means that these operators are overloaded only for that specific class.
One may try to replace new
and delete
operators for a number of reasons, namely:
There are a number of ways in which incorrect usage of new
and delete
may lead to the dreaded beasts of Undefined Behavior & Memory leaks. Respective examples of each are:
Using more than one delete
on new
ed memory & not calling delete
on memory allocated using new
.
An overloaded operator new
can keep a list of allocated addresses and the overloaded operator delete
can remove addresses from the list, then it is easy to detect such usage errors.
Similarly, a variety of programming mistakes can lead to data overruns(writing beyond the end of an allocated block) and underruns(writing prior to the beginning of an allocated block).
An Overloaded operator new
can over-allocate blocks and put known byte patterns ("signatures") before and after the memory made available to clients. The overloaded operator deletes can check to see if the signatures are still intact. Thus by checking if these signatures are not intact it is possible to determine that an overrun or under-run occurred sometime during the life of the allocated block, and operator delete can log that fact, along with the value of the offending pointer, thus helping in providing a good diagnostic information.
The new
and delete
operators work reasonably well for everybody, but optimally for nobody. This behavior arises from the fact that they are designed for general purpose use only. They have to accommodate allocation patterns ranging from the dynamic allocation of a few blocks that exist for the duration of the program to constant allocation and deallocation of a large number of short-lived objects. Eventually, the operator new
and operator delete
that ship with compilers take a middle-of-the-road strategy.
If you have a good understanding of your program's dynamic memory usage patterns, you can often find that custom versions of operator new and operator delete outperform (faster in performance, or require less memory up to 50%)the default ones. Of course, unless you are sure of what you are doing it is not a good idea to do this(don't even try this if you don't understand the intricacies involved).
Before thinking of replacing new
and delete
for improving efficiency as mentioned in #2, You should gather information about how your application/program uses dynamic allocation. You may want to collect information about:
Distribution of allocation blocks,
Distribution of lifetimes,
Order of allocations(FIFO or LIFO or random),
Understanding usage patterns changes over a period of time,maximum amount of dynamic memory used etc.
Also, sometimes you may need to collect usage information such as:
Count the number of dynamically objects of a class,
Restrict the number of objects being created using dynamic allocation etc.
All, this information can be collected by replacing the custom new
and delete
and adding the diagnostic collection mechanism in the overloaded new
and delete
.
new
:Many computer architectures require that data of particular types be placed in memory at particular kinds of addresses. For example, an architecture might require that pointers occur at addresses that are a multiple of four (i.e., be four-byte aligned) or that doubles must occur at addresses that are a multiple of eight (i.e., be eight-byte aligned). Failure to follow such constraints can lead to hardware exceptions at run-time. Other architectures are more forgiving, and may allow it to work though reducing the performance.The operator new
that ship with some compilers don't guarantee eight-byte alignment for dynamic allocations of doubles. In such cases, replacing the default operator new
with one that guarantees eight-byte alignment could yield big increases in program performance & can be a good reason to replace new
and delete
operators.
If you know that particular data structures are generally used together and you'd like to minimize the frequency of page faults when working on the data, it can make sense to create a separate heap for the data structures so they are clustered together on as few pages as possible. custom Placement versions of new
and delete
can make it possible to achieve such clustering.
Sometimes you want operators new and delete to do something that the compiler-provided versions don't offer.
For example: You might write a custom operator delete
that overwrites deallocated memory with zeros in order to increase the security of application data.
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