C++动态内存分配---两级allocator设计与实现(二)

引言

前文 提到allocator类将new操作符内存的分配与对象的构造或delete操作符对象的析构和内存的释放分为两个阶段。内存的分配拟和释放分别由::allocate()和::deallocate()负责;对象的构造和析构分别由 ::construct()和::destroy()负责。本文参考《STL源码剖析》和SGI STL实现,分析allocator类中的构造与析构。

destroy函数和construct函数的实现

construct函数很简单,只是利用placement new调用对象的构造函数。而destory函数就稍微复杂一些,利用了type_traits编程技巧,判断迭代器所指元素类型中是否有non-trivial 析构函数,如果没有则直接结束,否则依次调用析构函数。这样处理的话,万一需要对很大范围的对象执行析构函数,但是析构函数都是无关痛痒的(trivial)则没有必要一次次调用析构函数,这样能大大提高效率。

#include<new>
#include<iostream>
#include<type_traits>
template<class T1,class T2>
inline void construct(T1 *p, const T2& value){
    new (p)T1(value); //placement new;call T1::T1(value);
}

//destroy第一个版本,接受一个指针
template<class T>
inline void destroy(T* pointer){
    pointer->~T();
}

//第二个版本接受两个迭代器,释放一个范围的内存,利用type_traits<>根据不同类型求得最适当的措施
template<class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last){
    __destroy(first, last, std::_Val_type(first));
}

template<class ForwardIterator,class T>
inline void __destroy(ForwardIterator first, ForwardIterator last, T*){
    __destroy_aux(first, last, std::has_trivial_destructor<T>());
}

template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator first, ForwardIterator last, std::false_type){
    std::cout << "in false_type" << std::endl;
    for (; first < last; ++first)
        destroy(&(*first));
}

template<class ForwardIterator>
inline void __destroy_aux(ForwardIterator first, ForwardIterator last, std::true_type){
    std::cout << "in true_type" << std::endl;
}

SGI STL的实现

SGI STL是STL的经典实现之一,那么SGI是如何考虑allocator的设计呢?
1. 从heap申请空间
2. 考虑多线程
3. 考虑内存不足
4. 考虑内存碎片
为了简化问题,我们不考虑多线程的情况。

剩下的三个问题中,申请内存可以采用malloc和free库函数,内存不足也在其中相应的考虑。而内存碎片则需要更精细的考虑。

内存碎片

当程序同时处理一系列内存需求

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值