allocator

一、allocator 是什么?

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

标准库容器(vectorlistmap 等)都用它管理内存,默认是 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
相关推荐
༄沐࿆风࿆࿆11 小时前
JavaScript函数完全指南:从基础语法到闭包原理与应用实战
开发语言·javascript
KobeSacre12 小时前
DelayQueue 源码
java·开发语言
Let's Chat Coding12 小时前
身份识别、身份认证与授权的区别
c++
han_hanker12 小时前
重新认识枚举enum
开发语言
鹏易灵13 小时前
C++——8.移动语义初探(移动构造、移动赋值)
开发语言·c++·php
2601_9623413013 小时前
计算机毕业设计之jsp考研在线复习平台
java·大数据·开发语言·hadoop·python·考研·课程设计
凯瑟琳.奥古斯特13 小时前
力扣1008:前序重建BST
开发语言·c++·算法·leetcode·职场和发展
Alvin's Tech Blog13 小时前
内存泄漏会导致操作系统永久丢失内存吗?它会导致应用程序崩溃吗?
c++·内存管理·内存泄漏
会周易的程序员13 小时前
使用 LuaBridge 封装 C++ 日志库 microLog 为 Lua 模块
c++·物联网·junit·lua·日志·iot·aiot
2zcode13 小时前
项目文档:基于MATLAB图像处理的饮料瓶灌装液位检测系统设计与实现
开发语言·图像处理·matlab