分配器allocator
什么是Allocator
分配器是负责封装堆内存管理的对象,它们在整个标准库中使用,特别是STL容器使用它们来管理容器内部的所有内存分配,大部份情况下,程序员不用理会,标准容器使用默认的分配器称为std :: allocator,例如当你声明一个简单的vector对象时,C++编译器默认已经使用了内置的std::allocator,在标准库的vector模板当中,第二个模板参数_Alloc就是std::allocator,实际上,std::allocator也是一个类模板
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
}
每个容器实例中都有一个Allocator实例。它向分配器请求存储来存储元素。分配器应具备的基本成员函数如下:
- T*allocate(size_t n);分配足够的存储空间来存储T的n个实例,并返回指向它的指针
- void deallocate(T* p, size_t n) 释放分配的内存
- void construct(T* p, Args ... args);使用p指向的args参数构造一个对象,该接口在C++20中已被移除
- void destroy(T* p);调用p指向的对象的析构函数,该接口在C++20中已被移除
MyAllocator实现
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <unistd.h>
#include <limits>
template<class T>
class MyAllocator
{
public:
using size_type = size_t;
using pointer = T*;
using const_pointer = const T*;
using const_void_pointer = const void *;
using value_type = T;
MyAllocator() = default;
~MyAllocator() = default;
pointer allocate(size_type numObjects)
{
allocCount += numObjects;
std::cout << "MyAllocator::allocate,内存分配:" << numObjects << std::endl;
return static_cast<pointer>(operator new(sizeof(T)*numObjects));
}
//分配内存
pointer allocate(size_type numObjects, const_void_pointer hint)
{
std::cout << "allocate2" << std::endl;
return allocate(numObjects);
}
void deallocate(pointer p, size_type numObjects)
{
std::cout << "MyAllocator::deallocate,内存释放:" << numObjects << std::endl;
allocCount -= numObjects;
delete p;
}
//返回每次分配/删除的内存数
size_type get_allocations() const
{
return allocCount;
}
//分配器支持最大的内存数
size_type max_size() const
{
return std::numeric_limits<size_type>::max();
}
private:
size_type allocCount;
};
int main()
{
std::vector<int,MyAllocator<int>> v;
std::cout << "--------------" << std::endl;
for (size_t i = 0; i < 30; i++)
{
sleep(1);
v.push_back(i);
std::cout << "--------------" << std::endl;
std::cout << "当前容器内存占用量:" << v.get_allocator().get_allocations() << std::endl;
}
return 0;
}
用g++编译通过结果可以看出当内存不足vector会使用alloctor申请2倍大的内存(vs是1.5倍),不同编译申请的倍数可能不同