Allocator in STL
new
/delete
new operator
as our familiar new operator, includes 2 steps:operator new
to allocate memoryplacement new
to call constructor
delete operator
as our familiar delete operator, also includes 2 steps:- call destructor
operator delete
to 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 operator
directly. - 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 new
deallocate(_Tp* __p, size_t __n)
: calloperator delete
construct(_Up* __p, _Args&&... __args)
: callplacement new
destroy(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.