卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

  • STL 与容器

    • STL容器了解哪些
    • STL中allocator的作用
      • 简要回答
      • 详细回答
      • 代码示例
      • 知识拓展
    • STL中迭代器失效的场景
    • c++的map和unordered_map有什么区别和实现原理
    • map,deque,list的底层实现原理
    • unordered_map的rehash机制
    • vector底层原理和扩容过程
    • push_back()和emplace_back()的区别
  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# STL中allocator的作用

# 简要回答

Allocator是STL中负责内存管理的组件,它封装了内存分配和释放的细节,实现了容器与内存管理的解耦。

通过模板参数允许自定义内存分配策略,满足特殊的内存需求(如内存池、共享内存等)。

# 详细回答

核心职责:

内存分配:allocate() 分配原始内存

内存释放:deallocate() 释放已分配内存

对象构造:construct() 在已分配内存上构造对象

对象析构:destroy() 析构对象但不释放内存

设计理念:

分离关注点:容器关注数据结构,allocator关注内存管理

策略模式:通过模板参数注入不同的内存管理策略

类型安全:通过rebind机制支持容器内部数据结构的分配

# 代码示例

基本使用示例

#include <memory>
#include <vector>
#include <iostream>

void basic_allocator_usage() {
    // 默认allocator使用
    std::allocator<int> alloc;

    // 分配能容纳5个int的内存
    int* ptr = alloc.allocate(5);

    // 在分配的内存上构造对象
    for(int i = 0; i < 5; ++i) {
        alloc.construct(ptr + i, i * 10); // 构造对象:0, 10, 20, 30, 40
    }

    // 使用对象
    for(int i = 0; i < 5; ++i) {
        std::cout << ptr[i] << " "; // 输出:0 10 20 30 40
    }
    std::cout << std::endl;

    // 析构对象(但不释放内存)
    for(int i = 0; i < 5; ++i) {
        alloc.destroy(ptr + i);
    }

    // 释放内存
    alloc.deallocate(ptr, 5);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

自定义使用示例

#include <cstdlib>
#include <new>
#include <iostream>

// 简单的内存池allocator
template<typename T>
class SimplePoolAllocator {
public:
    using value_type = T;

    SimplePoolAllocator() = default;

    template<typename U>
    SimplePoolAllocator(const SimplePoolAllocator<U>&) {}

    T* allocate(std::size_t n) {
        std::cout << "Allocating " << n << " objects of size " << sizeof(T) << std::endl;
        if(auto p = static_cast<T*>(std::malloc(n * sizeof(T)))) {
            return p;
        }
        throw std::bad_alloc();
    }

    void deallocate(T* p, std::size_t n) {
        std::cout << "Deallocating " << n << " objects" << std::endl;
        std::free(p);
    }

    // C++17前需要定义construct/destroy
    template<typename U, typename... Args>
    void construct(U* p, Args&&... args) {
        new(p) U(std::forward<Args>(args)...);
    }

    template<typename U>
    void destroy(U* p) {
        p->~U();
    }
};

// 使用自定义allocator的vector
void custom_allocator_demo() {
    std::vector<int, SimplePoolAllocator<int>> vec;

    for(int i = 0; i < 5; ++i) {
        vec.push_back(i);
        std::cout << "Size: " << vec.size()
                  << ", Capacity: " << vec.capacity() << std::endl;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 知识拓展

  • 什么是rebind机制?

rebind机制是C++模板编程中的一种技术,它允许在一个类模板内部,使用不同的模板参数来重新定义(或“重新绑定”)自身或另一个类模板,从而生成一个全新的类型。

  • 知识图解 image

image

  • 适用场景

  • 面试官可能追问

Q1:"什么情况下应该使用自定义allocator?"

A1:需要内存池优化性能时,使用特殊内存区域(共享内存、GPU内存);需要内存使用监控和调试时,实现特定内存布局需求时

Q2:"自定义allocator需要注意哪些陷阱?"

A2:保证异常安全,正确处理对齐要求,实现正确的propagate_on_container_xxx特性,必要的时候保证线程安全性

Last Updated: 3/10/2026, 6:08:48 PM

← STL容器了解哪些 STL中迭代器失效的场景 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪