(四) 分配器allocator

分配器

  • 一般不建议直接使用分配器,它给容器分配内存,分配器的效率高低会直接影响容器的效率,包括速度和空间
  • 所有的分配动作,最终都会调用malloc(),这个函数再根据当前所处的操作系统不同,调用不同的操作系统API,拿到真正的内存

malloc

  • operator new()和delete底层都调用malloc()
  • malloc分配如下图,蓝色的内存,再搭配一整包东西返回
    • 附加的额外空间基本是固定的,如果所需的内存大,额外开销就小,如果所需的内存小,额外开销就大
    • 加的东西详细见内存管理

在这里插入图片描述

allocator

  • VC6所提供的分配器allocator
    • 当它要提供内存时调用的是allocate,它调用operator new(),后者再调用malloc
    • 当它想要释放内存时,调用deallocate,它再调用operator delete(), 后者调用free
  • VC6+的allocator只是以::operator new和::operator delete完成allocate()和deallocate(),没有任何特殊设计。底层是调用c的malloc和free释放和管理内存。这种用法在分配小空间时每次的额外开销都占比很大,VC没有对此做出优化。
//VC6所附加的标准库,其allocator的实现如下
template<class _Ty>
class allocator{
public:
	typedef _SIZE size_type;
	typedef _PDFT difference_type;
	typedef _Ty _FARQ *pointer;
	typedef _Ty value_type;
	//第一个参数表示想要多少个类型
	//第二个参数表示类型的名称是什么,void*可以传入任何类型
	pointer allocate(size_type _N, const void*)
	{ return (_Allocate((difference_type)_N, (pointer)0))); }
	void deallocate(void _FARQ *_P, size_type)
	{ operator delete(_P_; }
};

//_Allocate()定义如下
template<class _Ty> inline
_Ty _FARQ *_Allocate(_PDFT _N, _Ty _FARQ *)
{ if(_N < 0 ) _N = 0;
return ((_Ty _FARQ *) operator new((_SIZT) _N * sizeof(_Ty))); }
  • allocator< int >(),类模板加上参数后就称为了一个类的名称,直接加小括号就成为一个临时对象
  • 临时对象没有名称
//使用allocator,分配512ints
int *p = allocator<int>().sllocate(512, (int*)0);
//构建临时对象,通过deallocate释放已经分配的内存
//要传入参数表示当时申请的内存大小
allocator<int>().deallocate(p, 512);

alloc

  • G2.9中容器的默认分配器是alloc,它对额外开销做了优化

    • 额外开销主要是由于每次分配都有头尾两个cookie,占8个字节
    • malloc的分配,是针对不同的人来使用的,所以大小不一,但是容器中每个元素的大小都是一致的,所以可以从此入手优化
    • alloc设计了16条链表,每一条链表负则不同的区块,第0条链表负则的是8个字节的大小,第6条链表负则的是56个字节的大小,第15条负责的是168个字节的大小
    • 所有的容器,当它需要内存时,都向该分配器要内存,所有的容器大小都被调制到8的倍数。比如50调整到56,56是第6条链表负则的,查看该链表是否有内存块,如果没有,它再用malloc去向操作系统要一大块内存来做切分,切出来的东西再用单向链表串起来。这样获得的每一块内存就不带cookie,从而减少了开销。
  • G4.9版容器的分配器又回到了无优化的版本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值