6.分配器allocator

分配器allocator在C++中用于容器内存的高效管理,重点关注空间利用率和速度。主要函数包括内存申请的allocator和释放的deallocator。文章对比了VC6、BC5和GNUC STL中allocator的实现,分析了它们如何调用operator new/malloc和operator delete/free。GNUC的allocator旨在减少malloc次数以降低内存布局的overhead,但可能导致小元素额外开销较大。
摘要由CSDN通过智能技术生成

分配器allocator

​ 分配器是为容器分配内存的,效率相当重要

  1. 空间利用率

  2. 速度

    最重要的两个函数,内存的申请与回收

    1. allocator
    2. deallocator

1. Operator new() 和 malloc()

operator new() 会调用 malloc();

在这里插入图片描述

malloc分配的内存布局

在这里插入图片描述

  1. 0x41 cookie
  2. pad 表示填充
  3. debug mode会有固定的调试信息内容
  4. 具体的内容在c++内存管理中提到

VC6 STL 对allocator 的使用

在这里插入图片描述
在这里插入图片描述

​ vc的分配器调用 operator new -> malloc

​ vc的分配器调用 operator delete -> free

  • Vc6 的allocator调用的是operator new 和 operator delete ,没有特殊的设计

不鼓励直接使用分配器,但是可以帮助了解源代码

// 分配512个int
int* p = allocator<int>().allocate(512, (int*) 0); // 临时对象,没有名称
// 由第二个参数告诉分配器传入的是什么类型

// 归还给操作系统
allocator<int>(). deallocate(p, 512); // 不仅要告诉指针,还要告诉当初分配的元素个数

BC5 STL 对allocator 的使用

在这里插入图片描述
allocator 的实现
在这里插入图片描述

  • 也是没有任何特殊的设计
  • 如果容器放置了大量的元素,每个元素的size都很小,操作带来的额外的开销就会很大。
  • 提供了一个默认值,调用时可以少写一个参数

GNUC 实现的allocator

在这里插入图片描述
allocate调用的是全局的::allocate ,调用的也是operator new() -> malloc
deallocate调用的是全局的::deallocate, 调用的是operator delete() -> free

GNU (之前的版本SGI) STL 使用的是另一种allocator。实际上GNUC 用的是SGI的分配器 alloc
在这里插入图片描述

GNUC所使用的分配器alloc

在这里插入图片描述

​ 主要的诉求是减少malloc的次数,malloc会带有overhead(内存布局)额外的开销,overhead中最重要的就是上下两个cookie,记录了分配的内存容量(16的整数倍),free通过这个cookie来知道要回收内存的容量。

​ 0 - 15 个链表负责 8byte - 128 byte 容量的,比如申请50个字节,会调整到56,由链表#7负责管理。

​ 如果放100万元素,如果都不带cookie,会节省800 万 - 8字节的空间 cookie的数量会少很多。

  • 这种方式有一个很小的缺陷。

gnuc 4.9 allocator

在这里插入图片描述

  • 基类是 new_allocator
  • 内存分配和释放的动作没有特殊的设计
  • why? 没人知道hhh
  • alloc还在,__pool_alloc 就是2.9的alloc
    在这里插入图片描述

仍然可以使用,注意命名空间

vector<string, __gnu_cxx::__pool_alloc<string>> vec; 

结论

三个厂商的STL 分配器

  • 如果元素的size很小,那么操作带来的额外开销占比例就会很大
  • 如果元素的size大,那么操作带来的额外开销就没有那么大,可以让使用者接受,这可能就是要自己设计分配器的原因
  • 在现实中,元素的size都很小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值