c++ allocator类

目录

std::allocator::allocate

c++中的allocator类

概述

allocator用法

详解

allocate用于分配原始内存

Return value

在STL中也会用allocate类


std::allocator<T>::allocate

(1)

pointer allocate( size_type n, const void * hint = 0 );

(until C++17)

T* allocate( std::size_t n, const void * hint);

(since C++17)
(deprecated)
(removed in C++20)
(2)

T* allocate( std::size_t n );

(since C++17)
(until C++20)

[[nodiscard]] constexpr T* allocate( std::size_t n );

(since C++20)

c++中的allocator类

概述

  • 它用于将内存的分配和对象的构造分离开来. 它分配的内存是原始的、未构造的.
  • Throws std::bad_alloc if allocation fails.
  • 标准库中allocator类定义在头文件memory中
allocator<string> alloc;  // 定义了一个可以分配string的allocator对象
auto const p = alloc.allocate(n);  // 分配n个未初始化的string内存,即为n个空string分配了内存,分配的内存是原始的、未构造的

allocator用法

  • allocator a // 定义了一个名为a的allocator对象,它可以为类型T的对象分配内存
  • a.allocate(n) // 分配能保存n个类型为T的对象的内存
  • a.deallocate(p, n) // 释放T*指针p地址开始的内存,这块内存保存了n个类型为T的对象,p必须是一个先前由allocate返回的指针,且n必须是p创建时所要求的大小,且在调用该函数之前必须销毁在这片内存上创建的对象,这是因为在创建的过程中我们分配的是最原始的内存,所以在释放内存的时候也只能严格释放这片最原始的内存
  • a.construct(p, args) // p必须是一个类型为T*的指针,指向一片原始内存,arg将被传递给类型为T的构造函数,用来在p指向的原始内存上构建对象
  • a.destory(p) // p为T*类型的指针,用于对p指向的对象执行析构函数

详解

  • allocate用于分配原始内存

    • 正如前面说到,allocate出来的内存是最原始的,未构造的内存. 它的construct成员函数接受一个指针和零个或多个额外的参数,在给定位置构造对象, 额外的参数是用于初始化构造对象的
    auto q = p;  // q指向最后构造的元素之后的位置
    alloc.construct(q++);  // *q为空字符串
    alloc.construct(q++, 10, 'c');  // *q为cccccccccc
    alloc.construct(q++, "hi");  // *q为hi
    
    • 用完对象后,必须对这种构造的对象调用destory销毁,它接受一个指针,对指向的对象执行析构函数
    while(q != p)
    	alloc.destory(--q);

    循环开始处,q是指向最后构造的元素之后的一个位置,调用destory之前我们先对q进行递减操作,所以第一次调用destory销毁的是最后一个元素,依次执行销毁操作直到q和p相等. 我们只能对真正构造了的元素进行destory操作,一旦元素被销毁,就可以重新使用这部分内存来保存其他string或归还给系统,释放内存通过调用deallocate完成

    alloc.deallocate(p, n)

    其中p不能为空,必须指向allocate分配的内存,而且大小参数n也必须与调用allocate分配内存时提供的大小参数相等。

  • Return value

    Pointer to the first element of an array of n objects of type T whose elements have not been constructed yet.  就是返回未构造的第一个元素

在STL中也会用allocate类

#include <memory>

template <class T> class Vector {
public:
    Vector() : elements(0), first_free(0), end(0) {}
    void push_back(const T&);

private:
    static std::allocator<T> alloc; // object to get raw memory
    void reallocate();  // get more space and copy existing elements
    T* elements;        // pointer to first elment in the array
    T* first_free;      // pointer to first free element in the array
    T* end;             // pointer to one past the end of the array
};

template <class T> std::allocator<T> Vector<T>::alloc;

template <class T>
void Vector<T>::push_back(const T& t) {
    if (first_free == end) {
        reallocate();
    }
    alloc.construct(first_free, t);
    first_free++;
}

template <class T>
void Vector<T>::reallocate() {
    // compute size of current array and allocate space for twice as many elements
    std::ptrdiff_t size = first_free - elements;
    std::ptrdiff_t newcapacity = 2 * (size > 1 ? size : 1);//容量翻倍
    T* newelements = alloc.allocate(newcapacity);

    std::uninitialized_copy(elements, first_free, newelements);//元素拷贝

    for (T* p = first_free; p != elements; alloc.destroy(--p));//原来的空间的释放

    if (elements) {
        alloc.deallocate(elements, end - elements);
    }

    elements = newelements;
    first_free = elements + size;
    end = elements + newcapacity;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜猫程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值