Allocator in STL
new/delete
new operatoras our familiar new operator, includes 2 steps:operator newto allocate memoryplacement newto call constructor
delete operatoras our familiar delete operator, also includes 2 steps:- call destructor
operator deleteto release memory
new operator and delete operator are not allowed to overload, but operator new and operator delete are allowed.
Two tiers of memory allocators
STL provides two tiers of memory allocators:
- When size that allocation needs is large than 128KB, use
new operatordirectly. - Otherwise for small objects, a secondary memory allocator, or memory pool, is used, which is implemented through a free linked list.
The reason why to use two tiers of memory allocators is to reduce the frequency of mallocation and to reduce memory fragmentation.
The first tier
operator new
1 | |
placement new
A usage is:
1 | |
Another usage is:
1 | |
placement new is also a overloaded version of operator new! For instance:
1 | |
Don’t forget to call destructor before operator delete if placement new is adopted unless its destructor isn’t necessary. In other words, the object is a trivially destructible object. We can use std::is_trivially_destructible to distinguish whether it’s a trivially destructible object or not.
allocator
There are 4 functions inside allocator:
allocate(size_t __n): calloperator newdeallocate(_Tp* __p, size_t __n): calloperator deleteconstruct(_Up* __p, _Args&&... __args): callplacement newdestroy(pointer __p): call destructor~T()
Some contents unnecessary to understand are removed.
1 | |
The second tier
- Allocate a large buffer of memory;
- Split it into multiple blocks and chain them as lists;
- The memory pool has such 16 lists, each of which is responsible for different size. But they have a rule that the size of the back one is twice than the front’s. For example, the 1st list is responsible for blocks with 4 bytes and the 7th list is responsible for blocks with 256 bytes.