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
相关推荐
catchadmin6 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.4.1 发布,新增 MCP 支持
开发语言·php
zhanghaha13146 小时前
C++构造函数的一些其他应用(逐词逐句保姆讲解)
c++
jimy17 小时前
c++的 Type Traits (二、更详细版本)
开发语言·c++
狗凯之家源码网8 小时前
纯 PHP+MySQL 应用市场系统源码实测!
开发语言·mysql·php
dishugj8 小时前
系统架构风险点、敏感点和权衡点的概念和区分
java·开发语言
geovindu8 小时前
rust:Memento Pattern(续)
开发语言·后端·设计模式·rust·行为模式·备忘录模
马优晨8 小时前
JAVA 中 VO 实体类是什么意思,为什么要做这个
java·开发语言·状态模式·java vo·java vo是什么
Aurorar0rua8 小时前
CS50 x 2024 Notes Python - 01
开发语言·python·学习方法
茉莉玫瑰花茶9 小时前
GO [ 标准库 ]
开发语言·后端·golang
半杯咖啡半行码9 小时前
C++11核心特性详解:从C++11到C++20 的现代C++指南
开发语言·c++