标准库allocator类定义在头文件 <memory>中。它帮助我们将内存分配和构造分离开来,它分配的内存是原始的、未构造的。

类似vector,allocator也是一个模板类,我们在定义一个allocator类类型的时候需要制定它要分配内存的类型,它会根据给定的对象类型来确定恰当的内存大小和对齐位置:

allocator<string> alloc;
auto const p = alloc.allocate(n); // 分配n个未初始化的string

allocator类的操作:

allocator类及其算法
allocator<T> a 定义了一个名为a的allocator对象,可以为类型为T的对象分配内存
a.allocate(n) 分配一段原始的、未构造的内存,保存n个类型为T的对象
a.deallocate(p, n) 释放从T*指针p中地址开始的内存,这块内存保存了n个类型为T的对象;p必须是一个先前由allocate成员函数返回的指针,且n必须是创建时候的大小,在destroy之前,用户必须在这块内存上调用destroy函数
a.construct(p, args) p必须是一个类型为T*的指针,只想一块原始内存,args被传递给类型为T的构造函数
a.destroy(p) p为T*类型的指针,此算法对p执行析构函数
  • allcator分配未构造的内存
allocator分配的内存是未构造的,construct成员函数接受一个指针和零个或多个额外参数,在给定的位置构造一个元素,额外的参数用来初始化对象。这些额外参数必须和类型相匹配的合法的初始化器。
为了使用allocate返回的内存,我们必须用construct构造对象。
auto q = p;
alloc.construct(q++); // *q为空字符串
alloc.construct(q++, 10, 'c'); // *q为cccccccccc
alloc.construct(q++, "hi"); // *q为hi

还未构造对象的情况下或者是使用原始内存是错误的:

cout << *p << endl; // 正确,使用string的输出运算符
cout << *q << endl; // 错误,q指向未构造的内存

在这些对象使用结束后,我们使用destroy来销毁这些元素:

while (q != p)
alloc.destroy(--q);

元素被销毁后,如果需要将内存归还给系统,就需要调用deallocate函数:

alloc.deallocate(p, n);

传递给deallocate的指针不能为空,必须指向由allocate分配的内存,而且,n必须为allocate分配时的大小。

  • 拷贝和填充未初始化内存的算法
标准库为allocator类定义了两个伴随算法,可以在未初始化内存中创建对象:
allocator的算法
uninitialized_copy(b, e, b2) 从迭代器b和3
指出的输入范围中拷贝元素到迭代器b2指定的未构造的原始内存中,b2指向的内存必须足够大,能容下输入序列中的元素的拷贝
uninitialized_copy_n(b, n, b2) 从迭代器b指向的元素开始,拷贝n个元素到b2开始的原始内存中
uninitialized_fill(b, e, t) 在迭代器b和e指定的原始内存范围中创建对象,值均为t的拷贝
uninitialized_fill_n(b, n, t) 从迭代器b指向的原始内存地址开始创建n个对象,b必须指向足够大的未构造的原始内存,能容纳给定数量的对象

这些函数在给定目的位置创建元素,而不是由系统分配内存给他们。

vector<int> vec{0, 1, 2, 3, 4, 5};
auto p = alloc.allocate(vec.size() * 2);
auto q = uninitialized_copy(vec.begin(), vec.end(), p); uninitialize_fill_n(q, vec.size(), 42);

uninitialized_copy在给定位置构造元素,函数返回递增后的目的位置迭代器。因此,一个uninitialized_copy调用会返回一个指针,指向最后一个构造的元素之后的位置。

C++ Primer : 第十二章 : 动态内存之allocator类的更多相关文章

  1. C++ Primer : 第十二章 : 动态内存之shared_ptr类实例:StrBlob类

    StrBlob是一个管理string的类,借助标准库容器vector,以及动态内存管理类shared_ptr,我们将vector保存在动态内存里,这样就能在多个对象之间共享内存. 定义StrBlob类 ...

  2. C++ Primer : 第十二章 : 动态内存之shared_ptr类

    在C++中,动态内存是的管理是通过一对运算符来完成的:new  ,在动态内存中为对象分配空间并返回一个指向该对象的指针,delete接受一个动态对象的指针,销毁该对象,并释放该对象关联的内存. 动态内 ...

  3. C++ Primer : 第十二章 : 动态内存之shared_ptr与new的结合使用、智能指针异常

    shared_ptr和new结合使用 一个shared_ptr默认初始化为一个空指针.我们也可以使用new返回的指针来初始化一个shared_ptr: shared_ptr<double> ...

  4. C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)

    C++语言定义了两个运算符来分配和释放动态内存:运算符new分配内存,运算符delete释放new分配的内存. 运算符new和delete 使用new动态分配和初始化对象 在自由空间分配的内存是无名的 ...

  5. C++ Primer : 第十二章 : 动态内存之动态数组

    动态数组的分配和释放 new和数组 C++语言和标准库提供了一次分配一个对象数组的方法,定义了另一种new表达式语法.我们需要在类型名后跟一对方括号,在其中指明要分配的对象的数目. int* arr ...

  6. C++ Primer : 第十二章 : 动态内存之unique_ptr和weak_ptr

    unique_ptr 一个unique_ptr拥有它所管理的对象,与shared_ptr不同,unique_ptr指向的对象只能有一个用户.当unique_ptr被销毁后,它所指向的对象也被销毁. 定 ...

  7. C++ Primer 5th 第12章 动态内存

    练习12.1:在此代码的结尾,b1 和 b2 各包含多少个元素? StrBlob b1; { StrBlob b2 = {"a", "an", "th ...

  8. Linux内核设计与实现 总结笔记(第十二章)内存管理

    内核里的内存分配不像其他地方分配内存那么容易,内核的内存分配不能简单便捷的使用,分配机制也不能太复杂. 一.页 内核把页作为内存管理的基本单位,尽管处理器最小寻址坑是是字或者字节.但是内存管理单元MM ...

  9. C++Primer 第十二章

    //1.标准库提供了两种智能指针类型来管理动态对象,均定义在头文件memory中,声明在std命名空间. // shared_ptr:允许多个指针指向同一个对象. // unique_ptr:独占所指 ...

随机推荐

  1. SuperGridControl 使用小技巧

    1.显示行号 superGridControl1.PrimaryGrid.ShowRowGridIndex = true; 2.允许调整行头的宽度 superGridControl1.PrimaryG ...

  2. LibSVM使用指南

    LibSVM使用指南 一.     SVM简介 在进行下面的内容时我们认为你已经具备了数据挖掘的基础知识. SVM是新近出现的强大的数据挖掘工具,它在文本分类.手写文字识别.图像分类.生物序列分析等实 ...

  3. 自动登录 登陆成功那个alert遮盖一直存在bug

    手动登陆的时候,登陆成功MBProgressHUD message:@"登陆成功" 然后再dispatch_after 里调用MBProgressHUD hideHUD隐藏可以成功 ...

  4. 用K2 smartforms开发一个应用程序究竟比ASP.NET快多少?

    这次试验的起因是一场内部辩论. “用K2 smartforms开发一个应用程序究竟比ASP.NET快多少?” 我们推测是快4倍. 但是经过测试发现,我们推测错了. 本文记录了试验的规划.过程以及令人惊 ...

  5. SharePoint 2013 开发——APP开发的考虑和建议

    博客地址:http://blog.csdn.net/FoxDave 需要考虑的方面: 1. 记得CSOM授予网站集及以下的权限,而场解决方案需要整个场的访问权限. 2. 由于应用程序是彼此完全独立 ...

  6. SharePoint 2010 BCS - 概述

    博客地址 http://blog.csdn.net/foxdave SharePoint 2010首次引入了BCS的概念 - Business Connectivity Service,即业务连接服务 ...

  7. Android文件Apk下载变ZIP压缩包

    在azure云存储中 上传apk文件 使用ie下载 变成zip压缩包 解决方法 编辑 blob 属性和元数据 修改 内容类型 为 application/vnd.android.package-arc ...

  8. 有关PHP安装,基础学习

    首先要安装 wamp 和 NavicatMySQLFront (要在非中文目录下) 打开DW 点击站点 ——新建站点:设置站点名称,选择本地站点文件夹:wap\www 服务器:添加 +    服务器名 ...

  9. 2013年9月份第2周51Aspx源码发布详情

    休闲农庄企业站源码  2013-9-13 [VS2008]功能介绍:  首页功能:关于我们 资讯中心 休闲娱乐 餐饮娱乐 环境展示 园林展示 交通指引 联系我们  后台功能:      基本信息:服务 ...

  10. HDU 4737 A Bit Fun

    题意:定义F(i,j)为数组a中从ai到aj的或运算,求使F(i,j)<m的对数. 思路:或运算具有单调性,也就是只增不减,如果某个时刻结果大于等于m了,那么再往后一定也大于等于m.所以可以用两 ...