allocator类

一、简述

C++的STL中定义了很多容器,容器的第二个模板参数通常为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用于分配原始内存
正如标题所说,allocator出来的内存是最原始的,未构造的内存。相当于开辟新天地,我们将在这片新天地上盖高楼建大厦。它的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);  

——————————————————————————

六、总结

为什么会有allocator?
原因是new在内存分配上面有一些局限性,new的机制是将内存分配和对象构造组合在一起,同样的,delete也是将对象析构和内存释放组合在一起。但当分配一块大块内存时,我们想要自己在这块内存上构建对象,就像建房子,我们弄到一块地,想自己开发更赚钱,或更满足自己的需求,这中情况下我们希望将内存分配和对象构造分离,这样就可实现,我们可以事先得到大块内存,然后真正需要时就在这块内存上创建对象。
转自(http://blog.csdn.net/u012333003/article/details/22104939

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容