php网站下载器,电子商务网站建设模块,网站 模板下载,汉中市建设工程造价信息首先明确一点#xff0c;绝大多数情况下#xff0c;是标准库中的容器使用allocator。因为容器需要频繁的申请和释放内存。
一、容器使用allocator
典型的例子#xff1a;
vectorint , allocatorint a;但是为什么我们通常的定义vector变量的方法是#x…首先明确一点绝大多数情况下是标准库中的容器使用allocator。因为容器需要频繁的申请和释放内存。
一、容器使用allocator
典型的例子
vectorint , allocatorint a;但是为什么我们通常的定义vector变量的方法是
vectorint a;这就要看看stl里面vector的定义了
templatetypename _Tp, typename _Alloc std::allocator_Tp class vector : protected _Vector_base_Tp, _Alloc显然第二个参数是默认参数。如果我们什么也不输入则会传入一个实例化的类模板allocator。实例化的类型与容器元素类型一致。如果你故意传入一个类型不一致的allocator编译可以通过但是这种做法等于搬起石头砸自己的脚。
二、为什么容器需要allocator
容器在初始化、扩容、新增元素等情况下需要申请内存删除元素需要释放内存。allocator可以帮助我们做这个事情。这就有一个问题为什么 不直接用malloc和free函数 其实VC和BC版本的编译器allocator就是malloc和free套了个壳子加入了一些日志增加了一些错误处理而已。但是存在两个问题1多次malloc有cookie浪费2频繁malloc和free比较耗时。 在GC版本的编译器情况大不一样了。G4.9版本的编译器加入了内存池的思想可以有效解决上面的两个问题。 在侯捷老师的课中有这么一句话“频繁的malloc和free会产生大量的cookie浪费如果你有100万个元素就会浪费100万个cookie。”这句话其实不太严谨。当然侯捷老师举的例子是listlist如果想放置100万个元素自然要申请100万个空间在VC版本的分配器之下自然产生100万个cookie。但是如果是vector情况就不一样了可能一次就malloc了100万的空间cookie就只有一个。
三、VC、BC版本的分配器
没什么好说的就是套了个malloc和free。 比如说
vectorint a(100);那么在初始化的时候会调用malloc函数申请一块4*100字节的内存。
四、G4.9版本的分配器
分为两级分配器 1一级分配器就是原装的malloc和free。没什么好说的。当申请内存的大小超过128字节的时候调用一级分配器。
2二级分配器利用了线程池的思想适合分配小块内存。 结构如下 是一个长度为16的指针数组下拉链表。每个链表都是一个freelist就是内存池。关于freelist和内存池的概念可以参考前三篇博客。 长度16是为了适配不同的内存大小。内存块大小都是8的倍数从8到128。 假如要申请一块大小是6字节的内存那么上取8的倍数取8字节。到数组第一位找内存块。 申请内存的步骤为 1申请内存大小上取8的倍数找到对应的freeList拿内存块。 2如果freeList已经满了或者之前没申请过。那么malloc大块内存按照这个位置上的内存大小切片拉链表使用嵌入式指针。 释放步骤参考前三篇博客。
有个注意点 一个进程中只有一个二级分配器数据对象。因为数据结构、分配函数都是静态的。所以在这个进程中vector和list用的都是这一个分配器数据对象。