空间配置器——allocator

主要介绍一下allocator的用法

一、为什么要有allocator

为什么会有allocator?原因是new在内存分配上面有一些局限性,new的机制是将内存分配和对象构造组合在一起,同样的,delete也是将对象析构和内存释放组合在一起。但当分配一块大块内存时,我们想要自己在这块内存上构建对象,将分配空间和构造对象分离,就要用到allocator

 C++的STL中定义了很多容器,容器的第二个模板参数通常为allocator类型且有一个默认的allocator。标准库中allocator类定义在头文件memory中,用于帮助将内存分配和对象的构造分离开来。它分配的内存是原始的、未构造的。和vector等一样,allocator也是一个模板类,为了定义一个allocator对象,我们需指明这个allocator可以分配的对象类型,这样allocator好根据给定的对象类型来确定合适的内存空间大小和对齐位置,例:

allocator<string> alloc;  //定义了一个可以分配string的allocator对象
auto const p=alloc.allocate(n);  //分配n个未初始化的string内存,即为n个空string分配了内存
二、allocator用法概述
常见操作总结如下:

allocator<T> 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指向的对象执行析构函数

三、详情

1.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也必须与调用allocated分配内存时提供的大小参数相等。


三、拷贝和填充未初始化内存的算法

allocator还有两个伴随算法,用于在未初始化的内存块中创建对象,这些函数在给定目的位置创建元素,而不是由系统分配内存给他们,同样它们也位于头文件memory中。

uninitialized_copy(b,e,b2)      

  •  从迭代器b和e指出的输入范围中拷贝元素到迭代器b2指定的未构造的原始内存中,b2指向的内存必须足够大,能容纳输入序列中元素的拷贝。

uninitialized_copy_n(b,n,b2)  

  •  从迭代器b指向的元素开始,拷贝n个元素到b2开始的内存中

uninitialized_fill(b,e,t)              

  •  在迭代器b和e指定的原始内存范围中创建对象,对象的值均为t的拷贝

uninitalized_fiil_n(b,n,t)            

  •  在迭代器b指向的内存地址开始创建n个对象,b必须指向足够大的未构造的原始内存,能够容乃给定数量的对象

以上函数将返回一个迭代器,指向最后一个构造的元素之后的位置。


假定有一个int的vector,希望将它的内容拷贝到动态内存中,我们将分配一块比vector中元素所占空间大一倍的动态内存,然后将原vector中的元素拷贝到前一半空间,后一半用一个给定值进行填充。

//分配比vi向量所占空间大一倍的动态内存
auto p=alloc.allocate(vi.size()*2);
//通过拷贝vi中的元素来构造从p开始的元素
auto q=uninitialized_copy(vi.begin(),vi.end(),p);
//将剩余元素初始化为42
uninitialized_fill_n(q,vi.size(),42);



来源:C++ primer





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值