Item 50:understand when it makes sense to replace new and delete.
In item 49, we describe how to customize thenewError-handling functions, and how to overload your classoperator new。 Now we go back to the more fundamental question, why do we need to customizeoperator newOroperator delete?
- Detect usage errors.
newThe resulting memory if notdeleteCan cause memory leaks, and multipledeleteAlso throws undefined behavior. If you customizeoperator newTo save the address list for dynamic memory in thedeleteTo determine if the memory is complete, you can identify usage errors, avoid program crashes, and log the logs that are used by these errors.
- new and
delete is designed to be used for general purpose, by providing custom new , we can manually maintain a more suitable storage policy for the scenario.
- collect usage information. In the continuation of the custom
new , you may need to customize a new to collect address assignment information, such as how the dynamic memory block size is distributed? are allocations and recoveries FIFO or LIFO LIFO?
- To implement unconventional behavior. Consider security, for example, to
operator new initialize the new application's memory to 0.
- Other reasons, such as offsetting platform-related byte alignment, putting related objects together, and so on.
Customizing an operator new easy one, such as implementing a support cross-border check new :
Static Const int Signature = 0xDEADBEEF; //Boundary charactertypedef unsigned Char Byte; void* operator New(STD::size_t size) Throw(STD::Bad_alloc) { //Apply some memory to store placeholders size_t realsize = size + 2 * sizeof(int); //Request Memory void *Pmem = malloc(realsize); if (!Pmem) Throw Bad_alloc(); //write boundary character *(reinterpret_cast<int*>(static_cast<Byte*>(Pmem)+realsize-sizeof(int))) = *(static_cast<int*>(Pmem)) = Signature; //Return to true memory area return static_cast<Byte*>(Pmem) + sizeof(int);}
In fact, the above code is flawed:
- item 49 mentions
operator new should constantly call new handler, which is not followed in the code above;
- some architectures, different types are required to be placed in the corresponding memory location. For example
double should be an integer multiple of 8, int should be an integer multiple of 4. The code above may cause a run-time hardware error.
- start address alignment. C + + requires that the starting address for dynamic memory is byte-aligned for all types,
new and malloc follows this, but the address we return is offset by a int .
So far as you've seen, implementing one operator new is easy, but achieving a good one is operator new hard. In fact, we have other options: Read compiler documentation, business Tools for memory management, open source memory management tools, and more.
This address: http://harttle.com/2015/09/19/effective-cpp-50.html
Item 50: Why do I need to customize new and delete?