分配器allocator

分配器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倍),不同编译申请的倍数可能不同

posted @ 2022-06-21 10:26  不知云深处  阅读(168)  评论(0编辑  收藏  举报