STL中,对内存管理的alloc的设计,迫使我去学习了allocator类。这里对allocator内存管理做了点笔记留给自己后续查阅。allocator类声明、定义于头文件<memory>中的std命名空间内。所以,应该有以下内容位于文件头部…

#include <memory>
using namespace std; 文章目录
. 我们所知道的malloc和new
. C++中new的局限性
. 使用allocator将内存分配、对象构造分离开
. 我们所知道的malloc和new
再此之前,我只知道两种开辟内存的方式。 其一,可以使用C语言的函数malloc、realloc、calloc开辟内存,举个例子: int* ptr = (int *)malloc( * sizeof(int)); /* 进行强制类型转换 */ 其二,可以使用C++方式开辟内存,比如: int* ptr = new int[]; 对于,C风格的内存管理这里不做讨论。但是,对于C++的new风格,这里总结一下它的局限性。对于我个人来说,我一般写成这样new int[](),也就是在最后加一对小括号,因为C++保证这样可以将int[]中内存全部初始化为0。 . C++中new的局限性
对于以上这一段话,有一个话题需要弄清楚的,就是——内存构造。 对C++的new而言,它首先会()分配内存,然后自动的完成()对象构造。这里可以用侯捷先生翻译的《深度探索C++对象模型》一书中的伪代码来表示new的过程: Point* heap = __new(sizeof(Point));//开辟内存
if (head != ) {
head->Point::Point();//对象构造(内存构造)
} 注意,__new不表示new(它只是完成内存申请),以上整个伪代码过程为new所完成的功能。
正是因为new的这一连串的操作,造成了性能的下降。比如, auto p = new string[];
for (int i = ; i < ; ++i){
p[i] = "balaba...";
} 实际上,我只需要5个string,而new把100个对象全部构造好了(每个string已经被初始化为空字符串,也就是"")。 然后,接着又将p[-]赋值为balaba… 也就是前面将p[-]赋值为空字符串的操作,变得毫无意义。 . 使用allocator将内存分配、对象构造分离开
既然,new有它自身的局限性。对于性能要求极高的STL肯定是不会使用new的。好在有一个allocator类——它也是一个模板类,同时就是用来处理内存问题的。 allocator类将new的内存分配、对象构造,视作两个独立的过程,并由独立的函数负责。举个例子: allocator<char> str;
char* base = str.allocate(), *p = base; //内存分配
str.construct(p++, 'a'); //对象构造并初始化
str.construct(p++, 'b');
cout << base[] << base[]; 因为allocator是模板类,所以需要指定类型。接着,调用allocate()函数来分配内存(申请了10个char内存)。然后,使用construct函数构造base[]这块内存,并赋以初值a。 这就将new内存分配、内存构造给分离开了。一切,都像我们看到的那样。 同样,将delete的过程也拆分了开来。这是必须的,我们不能用delete去释放allocate分配的内存。 str.destroy(--p); //销毁对象
str.destroy(--p);
str.deallocate(base, ); //释放内存 小结:如果要使用allocate返回的内存,那么就必须先construct构造它。否则,你后续的行为都是未定义的(造成的后果也是严重的)。 但是,有几个例外。它们是uninitialized_copy、uninitialized_copy_n、uninitialized_fill和uninitialized_fill_n。从名字就知道uninitialized(未初始化的),它们的参数必须指向的是未构造的内存,比如uninitialized_copy会在给定位置构造元素。 有兴趣可以阅读《动态内存管理allocator类C++ STL标准模板库vector实现》看看它们的用法。
————————————————
版权声明:本文为CSDN博主「qingdujun」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qingdujun/article/details/85224771

浅谈C++ allocator内存管理(对比new的局限性)(转)的更多相关文章

  1. 12.Object-C--浅谈OC的内存管理机制

    昨天学习了OC的内存管理机制,今天想总结一下,所以接下来我要在这里bibi一下:OC的内存管理. 首先我要说的是,内存管理的作用范围. 内存管理的作用范围: 任何继承了NSObject的对象,对其他基 ...

  2. 浅谈Linux的内存管理机制

    转至:http://ixdba.blog.51cto.com/2895551/541355 一 物理内存和虚拟内存          我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此, ...

  3. 转:浅谈Linux的内存管理机制

    一 物理内存和虚拟内存          我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概 ...

  4. 浅谈C语言内存管理、内存泄露、堆栈

    1.内存分配区间:         对于一个C语言程序而言,内存空间主要由五个部分组成:代码段(.text).数据段(.data).静态区(.BSS).堆和栈组成.         BSS段:BSS段 ...

  5. Qt浅谈之一:内存泄露(总结)

    一.简介       Qt内存管理机制:Qt 在内部能够维护对象的层次结构.对于可视元素,这种层次结构就是子组件与父组件的关系:对于非可视元素,则是一个对象与另一个对象的从属关系.在 Qt 中,在 Q ...

  6. Qt浅谈之一:内存泄露(总结),对于QWidget可以setAttribute(Qt::WA_DeleteOnClose),而且绝对不能手动删除栈上的对象

    一.简介 Qt内存管理机制:Qt 在内部能够维护对象的层次结构.对于可视元素,这种层次结构就是子组件与父组件的关系:对于非可视元素,则是一个对象与另一个对象的从属关系.在 Qt 中,在 Qt 中,删除 ...

  7. 浅谈My SQL引擎的对比

    MySQL数 据库引擎取决于MySQL在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另外两种类型IN ...

  8. 浅谈Java的内存模型以及交互

    本文的内存模型只写虚拟机内存模型,物理机的不予描述. Java内存模型 在Java中,虚拟机将运行时区域分成6中,如下图:              程序计数器:用来记录当前线程执行到哪一步操作.在多 ...

  9. 浅谈checkpoint与内存缓存

    事务日志存在检查点checkpoint,把内存中脏数据库写入磁盘,以减少故障恢复的时间,在此之前有必要提下SQL Server内存到底存放了哪些数据? SQL Server内存使用 对SQL Serv ...

随机推荐

  1. Buffer-Overflow Vulnerability Lab

    实验概述 Buffer overflow 定义  Buffer overflow is defined as the condition in which a program attempts to ...

  2. [C#菜鸟]C# Hook (一)

    转过来的文章,出处已经不知道了,但只这篇步骤比较清晰,就贴出来了. 一.写在最前 本文的内容只想以最通俗的语言说明钩子的使用方法,具体到钩子的详细介绍可以参照下面的网址: http://www.mic ...

  3. Vue开发调试神器 vue-devtools

    Vue开发调试神器: vue-devtools 1. 下载Chrome扩展插件GitHub下载地址: https://github.com/vuejs/vue-devtools 建议使用npm淘宝镜像 ...

  4. 中国MOOC_零基础学Java语言_第4周 循环控制_2念整数

    2 念整数(5分) 题目内容: 你的程序要读入一个整数,范围是[-100000,100000].然后,用汉语拼音将这个整数的每一位输出出来. 如输入1234,则输出: yi er san si 注意, ...

  5. oracle 迁移数据文件

    步骤: 1.SQL>SELECT FILE_NAME FROM DBA_DATA_FILES; FILE_NAME --------------------------------------- ...

  6. DG on Windows 10 S: 执行任意代码

    DG on Windows 10 S: 执行任意代码 windows 10 S版本是什么鬼? 众所周知,我们使用的是windows 10企业版 LTSC.更准确一点,CMD运行winver,我的版本是 ...

  7. 【VS开发】C++调用外部程序

    关于三个SDK函数:WinExec, ShellExecute,CreateProcess的其他注意事项:[1]定义头文件必须定义以下两个头文件: [cpp] view plain copy #inc ...

  8. iptables添加开放端口

    查看状态 iptables -L -n 编辑/etc/sysconfig/iptables -A INPUT -p tcp -m tcp --dport 4000 -j ACCEPT 重启 servi ...

  9. Java实验3与第五周总结

    1.已知字符串:"this is a test of java".按要求执行以下操作:(要求源代码.结果截图.) •统计该字符串中字母s出现的次数. •统计该字符串中子串" ...

  10. 【Linux内核】编译与配置内核(arm)

    ARM平台使用的内核 (1)清除原有的配置与中间文件 make distclean(2)配置内核 make menuconfig ARCH=arm(3)编译内核 make uImage ARCH=ar ...