各类编译器 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之中