自定义分配器实现与内存池设计模式
如何编写一个满足C++分配器概念(Allocator Concept)的自定义分配器?请给出一个简单内存池分配器的设计框架,包括allocate/deallocate的实现要点、rebind支持、相等比较等。
回答
我还是少年
分配器概念要求:必须提供value_type、allocate(n)、deallocate(p, n)、rebind(通过allocator_traits)。可选:max_size()、construct/destroy。
简单内存池设计:
template<typename T>
class PoolAllocator {
public:
using value_type = T;
PoolAllocator() { /* 预分配大块内存 */ }
T* allocate(size_t n) {
if (free_list不空) 从free_list取一块;
else if (当前块有空间) 从块末尾分配;
else 申请新块(如4KB);
return ptr;
}
void deallocate(T* p, size_t n) {
p->~T();
将p归还到自由链表(free_list); // O(1)插入
}
// rebind支持:用allocator_traits自动生成
template<typename U> friend class PoolAllocator;
template<typename U> PoolAllocator(const PoolAllocator<U>&) {}
};
相等比较:相同内存池的分配器实例相等(==返回true),容器才可交换/拷贝。
设计要点:
- 线程安全(加锁或线程本地池)
- 对齐处理(对大于alignof(T)的类型)
- free_list管理释放的内存块(O(1)分配释放,但可能导致内存碎片和缓存不友好)
- 大块内存请求(>pool_block_size)回退到全局new
max_size()返回可用最大分配量
注意:C++17起分配器必须是可默认构造的(某些容器要求)。C++20的std::pmr提供了标准内存池分配器。