1. operator new() 和 malloc()
- 在C++中调用 new() ,最终都会根据所在不同的环境,比如 Linux,Windows 等等 malloc() 会调用不同的系统 api
- 我们所要求的大小,存放在 fill 区域,其他都是附加的
- 其中最重要的就是上下两个红色的部分,记录的是cookie,上下都有,消耗 8 个字节
- 我们要求的空间越小,附加的就越大
- 要求的越大,附加的就越小
2. VC6 对 allocator 的使用
- 都是默认使用 allocator class
- allocator 中有两个函数,一个是 allocate(),另一个是 deallocate()
- allocate() 解读:
-
- allocate() 中会调用 _Allocate()
- _Allcoate() 有会调用 operator new()
- operator new() 最终调用的是 malloc()
- deallocate() 解读:
-
- deallocate() 会调用 operator delete()
- operator delete() 会调用 C 中的 free()
- 在 VC6 中 allocator 只是利用 : :operator new() 和 : :operator delete() 来完成 allocate() 和 deallocate(),没有特殊设计
- 这里的 allocator<int>() 指的是临时对象
- 在我们 deallocator 的时候。不只是要传入指针,还要传入申请的大小,极其不便利
- 而容器使用分配器,就不会有这种不便
- 因为利用的是 malloc,根据前面的图,malloc时会有一段 overhead,这样就会多占用很多空间
3. BC5 STL 对 allocator 的使用
BC 在 C++ 编程领域通常指的是 "Bjarne's C++",它是由 C++ 语言的创始人 Bjarne Stroustrup 开发和推广的一种 C++ 编程环境。BC 平台旨在提供一个方便学习和实践 C++ 的工具集合,其中包括编译器、调试器和其他开发工具。它的全称是 "Bjarne's C++" 或者 "Bjarne's C++ Environment"。请注意,BC 平台不是一个官方的、广泛使用的 C++ 平台,而是由 Bjarne Stroustrup 个人推广的工具集合。
- 都是默认使用 allocator class
- allocator 中有两个函数,一个是 allocate(),另一个是 deallocate()
- 与 VC 类似,区别是 BC 5 allocator 的第二参数 默认是 0
- allocate() 解读:
-
- allocate() 中会调用 operator new()
- operator new() 最终调用的是 C 中的 malloc()
- deallocate() 解读:
-
- deallocate() 会调用 operator delete()
- operator delete() 会调用 C 中的 free()
- 在 BC5 中 allocator 只是利用 : :operator new() 和 : :operator delete() 来完成 allocate() 和 deallocate(),没有特殊设计
- 因为利用的是 malloc,根据前面的图,malloc时会有一段 overhead,这样就会多占用很多空间
4. GCC 2.9 中的 allocator
- allocator 中有两个函数,一个是 allocate(),另一个是 deallocate()
- 与 BC 相同
- allocate() 解读:
-
- allocate() 中会调用 operator new()
- operator new() 最终调用的是 C 中的 malloc()
- deallocate() 解读:
-
- deallocate() 会调用 operator delete()
- operator delete() 会调用 C 中的 free()
- G++ 中有注释,这个头文件没有被包含到任何一个其他头文件中,SGI STL 用的是不同的分配器
5. GCC 2.9 STL 对 allocator 的使用
- 默认使用都是 alloc ,4. GCC 2.9 中的 allocator 中给出的是 allocator
5.1. alloc 实现如下
- malloc 是给不同的场景来使用的,所以他需要有 overhead 来记录其他信息,比如记录它的 cookie(记录它的大小,额外开销主要就是 cookie,cookie 是上下都有,消耗的是 8 个字节) ,因为我们通过 malloc 拿到的是指针,最终要 free 的时候应该通过指针,查找到内存,并且通过 cookie 得知大小,并释放相应大小的内存
- 而容器不同,容器的大小是一样的不管有多少元素,元素大小是一样的,所以不必要附加记录每个元素的大小,容器分配内存,不需要那么多的 overhead,GCC 就对这个进行了优化
- GCC 设计了十六条链表
- #0 负责的是 8byte 大小的,接下去以 8 的倍数增长,如#1 16 byte
- 容器的元素大小会被调整到 8 的倍数 如 50 byte,就会调整到 56 byte,调整到 56 byte 后,就由 #6 链表来负责,这时候链表就检查,底下有没有内存块,没有才调用 malloc ,然后要一大块内存,并分割,分割后的用链表存储,分割出来的每一块就不带 cookie,cookie 的消耗是 8 个字节如果容器放 100 万个元素,就可以省去 800 万个字节的开销
cookie 详细参考:
6. GCC 4.9 STL 对 allocator 的使用
- 4.9 中的 allocator 继承了一个父类,父类是 __gun_cxx: : new_allocator
- 4.9 又回到了像 VC 和 BC 一样的做法,直接调用 operator new() 和 operator delete(),最终是 malloc() 和 free()
- 和 2.9 版的 alloc 相同的改了一个名称,改成了 __pool_alloc
- 如果要使用这个分配器,就可以给模板的第二个参数赋值 __gun_cxx : : __pool_alloc<string>