MST

星途 面试题库

面试题:C++ 标准库中 allocator 的深度定制

详细说明 C++ 标准库中 allocator 的工作原理。请设计并实现一个自定义的 allocator,该 allocator 能够在分配内存时记录每次分配的大小,并在释放内存时统计总的释放内存量。在一个使用自定义 allocator 的 std::vector 中进行多次元素插入和删除操作,并展示如何获取这些统计信息。
49.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

C++ 标准库中 allocator 的工作原理

  1. 内存分配与释放allocator 是 C++ 标准库中负责内存分配和释放的组件。它为容器(如 std::vectorstd::list 等)提供了一种抽象的内存管理方式。容器通过 allocator 来申请和释放元素所需要的内存空间。
  2. 类型感知allocator 是类型相关的,它知道要分配的对象的类型,因此可以正确地计算所需的内存大小,并进行类型安全的操作。例如,allocator<T> 知道 T 的大小和对齐要求。
  3. 构造与析构:除了分配和释放内存,allocator 还负责对象的构造和析构。construct 函数用于在已分配的内存上构造对象,destroy 函数用于析构对象。

自定义 allocator 的设计与实现

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

class MyAllocator {
private:
    size_t totalAllocatedSize = 0;
    size_t totalFreedSize = 0;

public:
    template <typename T>
    struct rebind {
        using other = MyAllocator;
    };

    MyAllocator() = default;

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

    ~MyAllocator() = default;

    T* allocate(size_t n) {
        totalAllocatedSize += n * sizeof(T);
        return static_cast<T*>(operator new(n * sizeof(T)));
    }

    void deallocate(T* p, size_t n) {
        totalFreedSize += n * sizeof(T);
        operator delete(p);
    }

    size_t getAllocatedSize() const {
        return totalAllocatedSize;
    }

    size_t getFreedSize() const {
        return totalFreedSize;
    }
};

在 std::vector 中使用自定义 allocator 并展示统计信息

int main() {
    using MyVector = std::vector<int, MyAllocator<int>>;
    MyVector vec;

    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);

    MyAllocator<int> alloc = vec.get_allocator();
    std::cout << "Total Allocated Size: " << alloc.getAllocatedSize() << " bytes" << std::endl;

    vec.pop_back();
    vec.pop_back();

    std::cout << "Total Freed Size: " << alloc.getFreedSize() << " bytes" << std::endl;

    return 0;
}

代码解释

  1. 自定义 allocator
    • MyAllocator 类包含两个成员变量 totalAllocatedSizetotalFreedSize 用于记录分配和释放的内存总量。
    • rebind 模板结构体是标准库要求的,用于在容器需要分配不同类型对象时进行适配。
    • allocate 函数负责分配内存并更新 totalAllocatedSize
    • deallocate 函数负责释放内存并更新 totalFreedSize
    • getAllocatedSizegetFreedSize 函数用于获取统计信息。
  2. 使用自定义 allocator 的 std::vector
    • 定义了 MyVector 类型,它是使用 MyAllocator<int>std::vector<int>
    • MyVector 进行插入和删除操作,并通过 get_allocator 获取 MyAllocator 对象,进而获取内存分配和释放的统计信息并输出。