之前的内容就不再叙述了
内存管理的形式
*前言 C++在malloc一大块内存的时候通常会使用一个指针去链接这些管理这些内存,delete时也没有将内存返回给操作系统*
内存管理的一个版本static allocator
为了避免在每个类中都定义如上的分割、回收函数,我们把这些函数抽象出来,集种写成类 allocator
1 | class allocator |
> 关于allocator函数的p的用法,展示认为可以这么做把
类需要做内存管理时需要将allocator声明为类的private静态成员,然后在重写operator new 和 delete时这么写就可以了
这个写法就十分简洁了,这样所有的内存分配都由allocator去担心
std:allocator
回忆在vc6下的malloc()所分配的内存格式
去查看vs2015的aloccator类源码发现allocate函数没有对内存进行管理,只是简单的申请了一块内存,没有特别之处。
值得一提的时在VS编译器下,STL的第二个模板参数都是alloctor模板类
GNU-C2.9 std::alloc
例如客户端程序执行vector<A,class Alloc=alloc>temp时,编译器会在free_list找到对应的接口来存储这个链表。找到接口的过程如下。
首先编译器计算size=sizeof(A)
每一个接口接管相应size的分配。例如,size=69就会到9条链表,size=96就回到11条链表
找到接口之后,编译器开始分配内存,首先编译器分配2*20个size的内存,一个用于划分内存、另外一个用于”战备转台“
所谓的战备状态 其实是以防有另一个size这样的链表需要分配,就可以直接的分配到这个里面
这样就能很好的实现cookie free
alloc会将容器发出的内存请求调整到8的整数倍。也就是容器中每个元素都要调整到8的倍数。alloc会挖出40个大小的内存来,其中20个来存储,20个备用
std::alloc 源码剖析
注意到在这个class里面的函数全是静态函数,相当于只是把全局的函数写到类中去。
refill函数在某一链表为空的时候进行“充值”。
注意:在alloc中没有free操作,只是战备池中的链表拉扯,这个内存没有泄露。是没有返还给操作系统,但是内存还是落在分配器手上(通过指针)。所以内存没有泄露。
refill函数实现
refill是在但钱链表为空的时候,申请20个区块。
通过嵌入式指针进行切割refill分配的内存。return链表的头结点。所谓的切割事实上是将指针转化为obj(obj为嵌入式指针),通过转char+n再转obj来实现。
chunk_alloc函数的实现源码剖析
chunk_alloc函数实现充值n*20个内存,而refill函数就是调用此函数,同时refill函数通过嵌入式指针(见前一条)实现切割。
传参为引用是因为有可能申请不了20个单位、通过操作指向pool那两个指针来实现。
若最后的是一块碎片,在判断碎片应该属于哪个链表,再拉指针,将碎片挂在链表上。