STL分析(二)分配器Allocator

申请内存

申请内存的操作最后都要落在malloc上
在这里插入图片描述
通常情况下,operator new会调用malloc函数进行分配。
关于new和delete,通过new调用对象总是先分配内存,再调用构造函数,delete相反。new分配的空间在堆区,需要delete显式释放

new和delete

new,delete与构造和析构函数的调用顺序

在这里插入图片描述

可以看见调用new时先分配内存,再调用构造函数。而调用delete时先调用析构函数,再释放内存。在动态分配的内存中,上下各有两个cookie各占4个字节,且分配的内存16字节对齐,若不满16字节的用padding补齐

当调用new和delete时编译器会发生一下转化
在这里插入图片描述
调用new[ ] 和 delete[ ]时
在这里插入图片描述
过程大概为先调用operator new函数分配内存,然后将指向该内存的指针进行静态转型为该类指针,再调用该类的构造函数。

调用new[ ]时要分配4+N*size个字节,由于开始的指针占4个字节
在这里插入图片描述
可以用 Foo *p = new Foo(7);的方式调用全局的new,也可以用::delete p;调用全局delete

重载operator new()

重载时第一个参数必须为size_t,且后面参数列唯一,后面的参数列为place arguments,调用时以new(...)输入place arguments。

重载operator delete()

只有当new所调用的ctor抛出异常时,才会调用重载版的operator delete(),用来归还未能创建成功的对象占用的内存。
在这里插入图片描述
在这个例子中在定义构造函数中抛出一个异常,下面是调用的方式:
在这里插入图片描述
通过调用Foo(1)来抛出构造时异常,并让重载的第三个delete函数去释放构造对象失败占用的内存。(G4.9版本没有调用operator delete(void*, long)但G2.9版本调用了)

标准库中的例子

在这里插入图片描述

allocate

在VC6,BC5中的allocator都是以operator::new和operator::delete完成allocate()和delete()
在这里插入图片描述
GC2.9设计的标准库中allocator也有这样的实现,但默认调用的分配器不是allocator,而是alloc。其设计如下
在这里插入图片描述
大致是定义不同的链表,链表分别存8bytes,16bytes…,256bytes字节的内存块,用完后在malloc一个新的内存块,省下了很多相同的cookie的开销。

但在GCC4.9的容器默认使用的变成了allocator,它的allocate()和deallocate()都是简单地调用了operator new()和operator delete(),并没有进行任何特殊处理。GCC2.9中的alloc变成了pool_alloc,除pool_alloc之外还有很多其他类型的分配器,都在ext文件夹中。要使用时用vector<string, _gnu_cxx::_pool_alloc<string>>使用该分配器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值