
std::allocator 是 C++ 标准库中默认的内存分配器模板,它封装了原始内存的申请与释放逻辑,让 STL 容器(如 vector、list、map)能与具体内存管理方式解耦。 它本身不直接操作 new/delete,而是通过 std::allocator_traits 间接调用 ::operator new 和 ::operator delete,提供类型安全、可定制、符合异常规范的内存接口。
allocator 的核心职责:分离“对象构造”与“内存分配”
STL 容器不直接 new T[] 或 delete[],而是分两步:
- 先用 allocator::allocate(n) 申请未初始化的原始内存(类似 malloc,但带 size_t 计算)
- 再用 allocator::construct(ptr, args...) 在该内存上就地构造对象(等价于 placement new)
- 析构时调用 allocator::destroy(ptr),仅调用析构函数,不释放内存
- 最后用 allocator::deallocate(ptr, n) 归还原始内存(类似 free)
这种分离让容器能支持无异常构造、自定义对齐、内存池等高级场景。
为什么默认 allocator 通常“透明”?
绝大多数情况下你无需显式写 allocator 类型——vector
立即学习“C++免费学习笔记(深入)”;
- allocate:调用 operator new(std::size_t)
- deallocate:调用 operator delete(void*, std::size_t)
- construct/destroy:分别委托给 std::construct_at / std::destroy_at(C++20 起)或 placement new / explicit destructor call
它不做内存复用、不缓存块、不记录类型信息,纯粹是薄封装,所以性能开销极小,也容易被编译器优化掉。
什么时候需要自定义 allocator?
真实项目中极少手写 allocator,但以下情况会用到:
- 嵌入式或实时系统:需确定性内存行为,避免全局堆碎片,改用静态缓冲区或专用内存池
- 高性能服务:为特定容器(如高频 push/pop 的 queue)绑定线程本地 arena,减少锁竞争
- 调试目的:加内存泄漏检测、越界检查(如 libc++ 的 __debug_allocator)
- 共享内存:让多个进程的容器使用同一段 mmap 内存(需满足 trivially copyable + 无指针成员)
注意:自定义 allocator 必须满足 Allocator 概念(C++17 起由 std::allocator_traits 约束),且所有容器实例必须使用相同 allocator 类型才能相互赋值或交换。
一个最小可运行的自定义 allocator 示例
下面是一个只重载 allocate/deallocate 的简易版本(省略 construct/destroy 等):
templatestruct simple_pool_allocator { using value_type = T; T* allocate(size_t n) { return static_cast (pool_allocate(n * sizeof(T))); } void deallocate(T* p, size_t) { pool_deallocate(p); } }; // 使用:std::vector > v;
真正生产级 allocator 还需处理对齐、传播特性(propagate_on_container_copy/move/swap_assignment)、最大分配数等,建议基于 std::pmr::polymorphic_allocator 或 boost::container::stable_vector 配套方案起步。
基本上就这些。allocator 不是日常编码要操心的部分,但理解它,就看清了 STL 容器“怎么拿到内存”和“怎么放回去”的底层契约。










