STL源码剖析笔记二

      在学习STL时,第一个需要知道的东西就是Allocator了,但是我们发现在使用STL时,几乎又用不着与Allocator相关的任何知识,这是因为STL将各个Container的实现中默认了所使用的Allocator,比如

std::vector<T, U=Alloc>,这里顺便提一下,在设计类模板的时候,可以给类型参数赋予默认值,当

用户没有特别的设置那个类型参数时,模板就使用默认的类型。

      Allocator也是一个模板,它帮助Container分配存储空间(主要指内存空间),构造存储空间,初始化存储空间。

一、内存的请求与分配

      在请求分配的存储空间时,不同的STL版本可能使用了不同的策略。我们知道,在我们使用c++编程时,当遇到需要在进程堆空间分配一块内存时,我们就使用new。但其实new语句在分配内存空间时,并不是简单的划分一块未使用区域给使用者,这其中必然包含了空闲空间的寻找。试想,如果当前进程空间中没有足够的空间供客户使用,或当前没有足够大的空闲空间但有许多零碎的小空间或许可以使用,如果你是new你该怎么办呢?所以,一般说来,全局作用域的operator new的效率可能不是很高,或者如果由我们自己来实现可能会更好,因为标准的库函数并不知我们在开发时系统的具体状态。

      在学习这部分之前,我们也需要了解一个知识点,就是operator new/delete。operator new具体来说有三种形式,具体的可以参考www.cplusplus.com对于operator new的描述。如果我们跟踪new的实现可以发现,他其实是通过malloc来实现的,其中还涉及到了异常情况的处理,就是说当内存分配的请求得不到时,该怎么办,如果你有心,你一定见过newhandle或setnewhandle这样的东西,newhandle其实是由用户来实现的特殊情况处理方法,也就是说如果分配失败我们该怎么办?如果我们提出了一个处理方法,可以通过setnewhandle来设置这个处理方法。如果在执行完客户提供的处理方法后,分配任务仍旧没有实现那就只能抛出异常了!

      显然我们可以改写内存分配的new操作,以提高程序的效率。根据STL源码剖析的描述,SGI版本的标注库的空间配置器,使用了一种称之为memory pool的技术。就是,在STL初始化时,先分配一些内存空间,这些空间以8bytes为最小单位,分成16种,分别是8、16、24、32、40、48、56、64、72、80、88、96、104、112、120、128字节,同样大小的空间通过指针连接在一起,组成一个个内存空间链表。当我们需要50bytes的空间时,配置器就从56bytes的链表中取出一块来交给我们使用,在使用完了之后再返还给它。这种方法是不是很不错,呵呵。但是,还需要考虑一些问题,比如:如果56bytes链表中没有空闲的空间给我怎么办?这个似乎还好解决,如果没有就找64bytes的链表。如果搜寻整个链表都没哟足够的空间怎么办?嗯,也许这时我们可以考虑设计一下我们的newhandle,让它来处理这种情况,比如可以释放一些空间什么的,然后我们再去寻找看有没有;如果还是没有,或许我们可以向系统再要些内存来,并把它们补充到内存池中,如果可以这个问题就可以解决了。如果,系统也没有空间那怎么办呢?哈哈,系统就会跑出类似于bad_alloc这样的异常了,我们的程序也只好无功而返了。

     就我所了解到的分配空间的过程,整体上类似如下的结构:

     while(true)

     {

           p = malloc(sizeof(Type)*N);

           if(!p)

               newhandle();

     }

      当然了,具体的实现还是有些复杂的,但是我们最关心的还是处理这些事情的一种思维方式。

 

二、内存空间的构造与初始化

    

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值