[STL源码剖析]空间置配器allocator

空间置配器allocator

placement new 与 new

new关键字操作:

  1. 调用operator new为对象申请内存
  2. 在申请到的内存地址上调用对象的构造函数
  3. 返回对象的地址

placement new的作用不是开辟新内存,是在指定内存块上构造对象

举例
class A {...};
class B {...};

A* pa = new A;
pa->~A();
B* pb = new (pa) B; //sizeof(B) <= sizeof(A)

在上面的代码中,pb并没有指向一块新开辟的内存,而是重用了pa指向的内存。直接在pa指向的内存上调用B的构造函数。

目的

placement new复用原有内存块,可以减小内存分配回收的开销。

构造与析构
constructor
  • 接受一个指针p和一个初值value,调用了placement new
  • new(p) T(value)
destory
  • 接受一个指针,析构其指向的对象
    • 直接调用析构函数
  • 接受first,last两个迭代器,将[first, last)内的对象析构
    • trivial destory:no-op
    • non-trivial destory:遍历每个对象并调用destory
    • 目的:减少trivial destory的开销。
空间的配置与释放
双层级配置器
  • 第一级配置器
    • 直接使用malloc(),free()
    • 模拟C++的set_new_handler()以处理内存不足的状况。
  • 第二级配置器
    • 当配置区超过128bytes,调用第一级配置器
    • 当配置区小于128bytes,采用自由链表(free list)+内存池(memory pool)处理。16个自由链表负责16个小型区块的次配置能力。内存池以malloc()配置而得。如果内存不足,转调用第一级配置器(那有处理程序)。
set_new_handler

函数原型:
std::new_handler set_new_handler( std::new_handler new_p )
当allocator空间分配失败时,调用new_handler函数,如果函数返回null pointer value,则抛出bad_alloc异常

内存基本处理工具

五个全局函数,作用于未初始化空间:

  • ctor
  • dtor
  • uninitialized_copy
    • 特化:
      • char:memmove()
      • wchar:memmove()
    • 泛化:
      • non-POD:construct()
      • POD:copy()
  • uninitialized_fill
    • non-POD:construct()
    • POD:fill()
  • uninitialized_fill_n
    • non-POD:construct()
    • POD:fill_n()
Plain Old Data, POD

POD型别必然有trivial ctor/dtor/copy/assignment函数,如标量型别(scalar types)或传统的C struct型别
因此对POD型别采取最高效率的方法,对non-POD采用最安全的方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值