allocator

一、allocator 是什么?

分配器 = 封装了"内存分配/释放" + "对象构造/销毁" 的类模板

标准库容器(vector、list、map 等)都用它管理内存,默认是 std::allocator<T>。


二、为什么需要 allocator?

直接 new/delete 的问题

cpp 复制代码
// new 做了两件事,绑定在一起:
T* p = new T();   // ① 分配内存  +  ② 构造对象
delete p;         // ① 析构对象  +  ② 释放内存

问题:有时只想分配内存,不想构造对象;或者想先构造,晚些释放。

allocator 把四步拆开

表格

操作 函数 含义
分配内存 allocate(n) 只分配 n 个对象的原始内存(未初始化)
构造对象 construct(p, args) 在已分配的内存上构造对象
析构对象 destroy(p) 调用析构函数,不释放内存
释放内存 deallocate(p, n) 归还内存给系统

三、标准使用方式

cpp 复制代码
#include <memory>

std::allocator<int> alloc;      // 创建分配器

// 1. 分配内存:10 个 int 的空间,未初始化
int* p = alloc.allocate(10);

// 2. 构造对象:在 p[0] 位置构造一个 int = 42
alloc.construct(p, 42);         // C++17 前
// 或
std::allocator_traits<decltype(alloc)>::construct(alloc, p, 42);

// 3. 使用对象
std::cout << *p;  // 42

// 4. 析构对象:只销毁,内存还在
alloc.destroy(p);               // C++17 前

// 5. 释放内存:归还 10 个 int 的空间
alloc.deallocate(p, 10);

四、C++17 的变化

C++17 起 construct/destroy 被标记为废弃 ,推荐用 allocator_traits 或直接 std::construct_at:

cpp 复制代码
#include <memory>

std::allocator<int> alloc;
int* p = alloc.allocate(1);

// C++17 推荐方式:
std::construct_at(p, 42);   // 构造
std::destroy_at(p);         // 析构

alloc.deallocate(p, 1);

五、自定义 allocator(实战)

场景:跟踪内存分配、使用内存池

cpp 复制代码
template <typename T>
class TrackingAllocator {
public:
    using value_type = T;

    TrackingAllocator() = default;
    template <typename U>
    TrackingAllocator(const TrackingAllocator<U>&) {}

    // 分配内存
    T* allocate(std::size_t n) {
        std::size_t bytes = n * sizeof(T);
        std::cout << "分配 " << bytes << " 字节\n";
        return static_cast<T*>(::operator new(bytes));
    }

    // 释放内存
    void deallocate(T* p, std::size_t n) {
        std::cout << "释放 " << n * sizeof(T) << " 字节\n";
        ::operator delete(p);
    }
};

// 使用自定义分配器的容器
std::vector<int, TrackingAllocator<int>> vec;
vec.push_back(1);  // 输出:分配 4 字节(或更多,vector 会预分配)

六、allocator 与容器的配合

cpp 复制代码
// 标准 vector 的第二个模板参数就是 allocator
template <typename T, typename Allocator = std::allocator<T>>
class vector;

// 默认使用 std::allocator
std::vector<int> v1;  // = std::vector<int, std::allocator<int>>

// 自定义 allocator
std::vector<int, TrackingAllocator<int>> v2;

七、一句话总结

问题 答案
allocator 是什么? 把"内存分配"和"对象构造"解耦的工具
为什么要用它? 精细控制内存生命周期,支持自定义分配策略(内存池、跟踪等)
谁在用? 所有标准库容器默认都用 std::allocator
现代 C++ 注意? C++17 起 construct/destroy 废弃,用 std::construct_at/destroy_at
相关推荐
yeccheng1 小时前
MySQL 索引超详解:从底层 B+ 树到面试高频考点
java·开发语言·jvm·mysql·面试
联犀1 小时前
纯 Go 的 CAD 开源库 go-cad:直接解析 DWG/DXF,现在也能导出 PDF
开发语言·golang·pdf
zjxtxdy1 小时前
C++面向对象程序开发-类与对象
开发语言·c++
東隅已逝,桑榆非晚3 小时前
算法6. 双指针法-查找总价格为目标的两个商品
c++·学习·算法
qq_406981034 小时前
c++拷贝构造函数
开发语言·c++
爱喝雪碧的可乐4 小时前
MATLAB
开发语言·算法·matlab
H.莓飛6 小时前
【C++】【STL】vector_OJ题
linux·服务器·开发语言·数据结构·c++·visual studio
Rabitebla6 小时前
【Linux操作系统】进程篇(十一):进程程序替换——从底层原理到 exec 函数族
linux·服务器·c++·笔记·学习·算法
沫璃染墨6 小时前
从零入门计算机网络系列(十五):TCP可靠传输机制详解——从序号与确认应答到乱序处理
服务器·网络·c++·tcp/ip·tcp
青少儿编程课堂7 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:Bellman-Ford与SPFA含负权最短路及负环检测全解析
c++·python·算法·bfs·信息学竞赛