各类编译器 allocator 底层

我们在c++中创建数组通常使用new来分配我们需要的内存大小,之后通过delete进行释放内存

但是我们调用new的时候,通过调用的是operator new,二operator new调用的是malloc,所以我们说new的本质其实就是malloc,只不过我们看不到而已,同样,delete调用operator delete ,进而调用free

我们通常会告诉编译器我们需要多大的内存空间,也就是传一个size参数,但是编译器所开辟的空间就不知size那么大了,他开辟的空间比size的,如上图,我们malloc size的大小,但是编译器确为我们开辟上面那么多的内存空间,这样反应了一个问题,如果我们的ssize很小,那么额外空间所占的比例就大,如果我们开辟的空间小,那么额外空间所占的比例就小,我们在这里不能说额外空间有多浪费,或者具体有多大,我们只能研究他所占的比例相对于一次malloc所有的内存占得大小而已,这额外空间中,有两个是必须就是上图边界的两个紫色部分,这叫做cookie,最上面的cookie里面存着整个空间的大小,方便我们delete的时候,我们直接通过首地址释放cookie里面存的大小内存就可以了,提高效率

上面大家可以看到各种容器使用的也都是allocator,这个源代码是VC,BC通用的(大致相同),allocator的原理和new是一样的,也是调用operator new,进而调用malloc,相同,deallocator 调用的是operator delete,进而调用free

同时,因为我们看到了源代码,所以我们可以手动使用分配器

int *p=allocaort<int>()._Allocator(10,(int *)0);

allocaort<int>().deallocator(p,10);

allocaort<int>()的意思就是一个对象allocator<int>制定了模板类,加上()其实就变成了一个临时的object

*************************************************************************************

GCC2.9

上面大家可以看到在gcc2.9编译器中,默认使用的分配器不是allocator,而是alloc,why?

实际上在gcc2.9中allocator仍然还是存在的,只不过编译器不用,使用alloc,当时认为alloccator过于浪费,因为每次malloc需要分配内存的时候,分配的内存都有很多的额外的内存开销,所以,alloc产生了,alloc的结构如下,他有16个连续·的链表,每一个指向一段内存空间,第一个指向8个字节的,第二个指向16个字节,依次类推,分别增加8个,当编译器malloc的时候,加入需要50个。他会找到底7个位置,开辟56个内存,这样的话就不必要那么多额外的空间消费,,,,,,,,但是到gcc4.9又开始默认使用allocator,

gcc4.9又开始使用allocator但是变了,源代码中allocator继承了alloccator base,但是define宏定义发现,他是newallocator,内部又是allocator,之后operator new, 进而malloc,本质还是malloc,但是alloc并没有删除,他被应用到了一些其他的分配器中,比如最后一张图,他被分配到了——poll allocator之中

时间: 2024-08-14 10:34:06

各类编译器 allocator 底层的相关文章

c++ 虚函数详解

下面是对C++的虚函数的理解. 一,定义 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离:用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略.下面来看一段简单的代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 classA { publi

异步编程系列第04章 编写Async方法

p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提高下英文,用我拙劣的英文翻译一些重要的部分,纯属娱乐,简单分享,保持学习,谨记谦虚. 如果你觉得这件事儿没意义翻译的又差,尽情的踩吧.如果你觉得值得鼓励,感谢留下你的赞,愿爱技术的园友们在今后每一次应该猛烈突破的时候,不选择知难而退.在每一次应该独立思考的时候,不选择随波逐流,应该全力以赴的时候,不选择尽力而

异步编程系列第03章 自己写异步代码

p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提高下英文,用我拙劣的英文翻译一些重要的部分,纯属娱乐,简单分享,保持学习,谨记谦虚. 如果你觉得这件事儿没意义翻译的又差,尽情的踩吧.如果你觉得值得鼓励,感谢留下你的赞,愿爱技术的园友们在今后每一次应该猛烈突破的时候,不选择知难而退.在每一次应该独立思考的时候,不选择随波逐流,应该全力以赴的时候,不选择尽力而

《Effective C++》资源管理:条款20-条款21

条款20:宁以pass-by-reference-to-const替换pass-by-value 在默认情况下,C++函数传递参数是继承C的方式,是值传递(pass by value).这样传递的都是实际实参的副本,这个副本是通过调用复制构造函数来创建的.有时候创建副本代价非常昂贵.例如一下继承体系 class Person{ public: Person(); virtual ~Person(); -- private: std::string name; std::string addres

资深人士剖析微软开源.NET事件:战略重心已经从PC转移到云端

本文是雷锋网对我的访谈整理的文章,源地址是 http://www.leiphone.com/news/201411/6KaGhD7PDABnvrRf.html 2014年11月13日,微软表示开源.NET,包含整个.NET服务器端的核心类别,ASP.NET 5.0..NET Common Language Runtime(CLR).Just-In-Time Compiler.Garbage Collector以及Base Class Libraries等,都在开源的范畴之中.0 0 消息一出,霎

算法学习 - 递归与非递归,位运算与乘除法速度比较

递归调用非递归调用 运行时间比较 结论 位运算与乘除法 结论 递归调用/非递归调用 我们都知道,很多算法,都是用递归实现的.当然它们同时也是可以用非递归来实现. 一般我们在对二叉树进行遍历的时候,还有求斐波那契数的时候,递归是非常简单的.代码容易懂,好实现. 但是递归的时候,有一个问题,就是需要压栈.为什么要压栈呢?因为当我在函数内部调用自身的时候,要中断当前的操作继续跳转到下一次的实现,而当前运行的状态要保存起来.所以就把当前状态进行压栈,等到运行到递归条件结束的时候,再弹栈. 所以递归就是需

&lt;&lt;Effective c++&gt;&gt;读书笔记---条款20:宁以pass-by-reference-to-const替换pass-by-value

尽量以pass-by-reference-to-const替换pass-by-value.前者通常比较高效,因为它可以避免调用拷贝构造函数和析构函数,并且可以避免切割问题.一下是一个很好的切片问题实例: class A { public: A() {} virtual ~A() {} virtual void Display() { cout << "A::Display()" << endl; } }; class B : public A { public:

关于 Spring AOP (AspectJ) 你该知晓的一切

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54629058 出自[zejian的博客] 关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容

Objective-C 中的类和对象

http://blog.ibireme.com/2013/11/25/objc-object/ Objective-C的runtime是开源的,源码可以在苹果官网下载到:objc4. 在objc4-532.2以后,苹果把NSObject的实现也挪进来了.想要了解NSObject底层实现终于不用去抠GNUstep了- 好了,下面正文: 1.id和Class的定义 runtime里面,声明了id和Class的类型,简化一下如下: 1 2 3 4 5 6 7 8 9 struct objc_class