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
相关推荐
Felven12 分钟前
C2. Potions (Hard Version)
c++
鸿芯微控科技13 分钟前
压电点胶阀出胶量不稳定怎么排查?驱动波形、背压、点胶重量与Python分析
开发语言·python·压电点胶阀·精密点胶·点胶重量·流体控制
原野池予24 分钟前
深入Java集合框架:HashMap源码解析(JDK 8)
java·开发语言
测试运维日常笔记34 分钟前
VMware vSphere、ESXi 与 vCenter Server:核心概念与关系详解
java·开发语言
Tyler_TXZ1 小时前
C++C语言之——树
c语言·c++·算法·
m0_547486661 小时前
《面向对象与Java程序设计》全套PPT课件2026
java·开发语言
旖旎夜光1 小时前
LeetCode 30:串联所有单词的子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
星恒随风1 小时前
C++ 红黑树封装(二):迭代器、const_iterator 与 operator[] 完整实现 mymap 和 myset
开发语言·c++·状态模式
jason成都1 小时前
ignav-next|Java 层封装 GNSS/INS 组合导航框架,隔离 RTKLIB 与 INS 内核,双模块独立演进、最小侵入
java·开发语言
抓不住时间的沙1 小时前
butterfly主题美化,打造属于自己的个性博客
java·开发语言·前端·javascript·node.js·github