C++ 标准库中 allocator 的工作原理
- 内存分配与释放:
allocator
是 C++ 标准库中负责内存分配和释放的组件。它为容器(如 std::vector
、std::list
等)提供了一种抽象的内存管理方式。容器通过 allocator
来申请和释放元素所需要的内存空间。
- 类型感知:
allocator
是类型相关的,它知道要分配的对象的类型,因此可以正确地计算所需的内存大小,并进行类型安全的操作。例如,allocator<T>
知道 T
的大小和对齐要求。
- 构造与析构:除了分配和释放内存,
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;
}
代码解释
- 自定义 allocator:
MyAllocator
类包含两个成员变量 totalAllocatedSize
和 totalFreedSize
用于记录分配和释放的内存总量。
rebind
模板结构体是标准库要求的,用于在容器需要分配不同类型对象时进行适配。
allocate
函数负责分配内存并更新 totalAllocatedSize
。
deallocate
函数负责释放内存并更新 totalFreedSize
。
getAllocatedSize
和 getFreedSize
函数用于获取统计信息。
- 使用自定义 allocator 的 std::vector:
- 定义了
MyVector
类型,它是使用 MyAllocator<int>
的 std::vector<int>
。
- 对
MyVector
进行插入和删除操作,并通过 get_allocator
获取 MyAllocator
对象,进而获取内存分配和释放的统计信息并输出。