剖析SGI STL空间配置器(allocate内存分配函数)

剖析SGI STL空间配置器(allocate内存分配函数)

要理解allocate函数是如何分配内存,就要先知道他是怎么管理内存的。
allocate函数的定义如下:

/* __n must be > 0      */
  static void* allocate(size_t __n)
  {
    void* __ret = 0;

    if (__n > (size_t) _MAX_BYTES) {
      __ret = malloc_alloc::allocate(__n);
    }
    else {
      _Obj* __STL_VOLATILE* __my_free_list
          = _S_free_list + _S_freelist_index(__n);
      // Acquire the lock here with a constructor call.
      // This ensures that it is released in exit or during stack
      // unwinding.
#     ifndef _NOTHREADS
      /*REFERENCED*/
      _Lock __lock_instance;
#     endif
      _Obj* __RESTRICT __result = *__my_free_list;
      if (__result == 0)
        __ret = _S_refill(_S_round_up(__n));
      else {
        *__my_free_list = __result -> _M_free_list_link;
        __ret = __result;
      }
    }

    return __ret;
  };

参数__n是要申请内存的大小,如果大于128字节,就不受二级空间配置器管理,直接通过malloc申请,但不是简单的只做malloc,对其进行了一层封装,在malloc失败时会有异常处理,具体怎么处理后面介绍。
而如果申请的内存大小 小于128字节,就会到二级空间配置器来处理了。二级空间配置器的结构如下图:
在这里插入图片描述

自由链表_S_free_list的结点存放一条链表,链表的的起始地址表示一块大小为(下标+1)8的内存,要在二级空间配置器上申请一块内存,需要获取对应大小内存在自由链表的下标,_Obj* __STL_VOLATILE* __my_free_list = _S_free_list + _S_freelist_index(__n);这句的代码就是用来定位的,需要注意是用一个二级指针接收的,如果__my_free_list为空,表示没有对应大小的内存块,这时候就需要调用_S_refill函数取填充了,具体怎么填充后面介绍。如果不为空表示有对应大小的内存块,直接把链表的第一个结点返回给用户,再更新链表头节点即可。

#     ifndef _NOTHREADS
      /*REFERENCED*/
      _Lock __lock_instance;
#     endif

在多线程环境下,因为自由链表定义在数据段,自由链表需要互斥的访问,在C++STL的设计完全没有考虑多线程,而SGI STL是线程安全的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_200_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值