Item5: use the same form of new and delete
Simply put, a single object and an array should be treated differently. C ++ uses [] to identify whether this is a single object or an array. Therefore, use Delete [] When there is [] in new.
Item6: Remember to deal with pointer member with delete In destructor
To prevent memory leakage, we need to do three things:
- Each constructor initializes the pointer.
- Delete the original memory in each assignment operator and reconfigure one
- In each destructor, the delete pointer
Item7: Preparations for insufficient memory
When the operator new application memory is not satisfied, the handler set by the user will be called before the STD: bad_alloc is thrown, and the call will find enough memory to stop.
Typedef void (* new_handler )();
New_handler set_new_handler (new_handler p) Throw (); |
Therefore, to define new handler, follow the following principles:
- Make more memory available
- If you cannot handle it yourself, install a different new handler
- Uninstall the new handler and throw STD: bad_alloc.
- Directly call abort or exit
Currently, the standard operator new throws an STD: bad_alloc exception. In fact, there are very few situations where you cannot apply for memory. Follow the standard practice. After a bad_alloc exception is thrown, record and analyze the logs. In this case, add the memory.
Item8: conventions to be followed when writing operator new and operator Delete
Write operator new by yourself, which must be consistent with the default behavior. in details, the new conventions should be followed as follows:
Void * operator new (size_t size)
{
If (size = 0) {// 1. The new value with the size of 0 can also be successful.
Size = 1;
}
While (true) {// 2. keep repeating and try to apply for memory
If (alloc success) return * pointer // 3. the pointer is returned successfully.
// 4. Failed, handling error
New_handler globalhandler = set_new_handler (0 );
Set_new_handler (globalhandler );
If (globalhandler) (* globalhandler )();
Else throw STD: bad_alloc (); // 5. If no processing function is available, an exception is thrown.
}
} |
Delete should follow a simple rule, that is, deleting a null pointer is always safe.
Void operator Delete (void * rawmemory)
{
If (rawmemory = 0) return;
Otherwise, delete the memory.
} |
Item9: Avoid hiding the formal form of new
In C ++, the declaration in the internal scope will hide the same external name. Clause 9 illustrates a special case. You have written a custom operator new and received a new_handler as follows:
Void * operator new (size_t size, new_handler P) |
This operator new will mask the default operator new. You cannot call the default new operation. There are two solutions to this problem, one is to declare another operator new (size_t size), the other is to use the default parameter operator new (size_t size, new_handler p = 0)
Item10: If you write an operator new, write an operator Delete
Clause 10 actually explains the reason for using operator New: Improving the memory usage efficiency.
The default operator new needs to use a space before the returned pointer to record the size occupied by the pointer (the space is called Cookie) for normal operation of Delete. If operator new is reloaded, you can manage the block by yourself to reduce memory usage.
Implement the memory pool. Each time you apply from the memory pool, if the memory pool is not enough, it will expand.
Therefore, after writing an operator new, you need to write an operator Delete, because only you know How to Apply for memory.