剖析SGI STL空间配置器(deallocate内存回收函数和reallocate内存扩充函数)

剖析SGI STL空间配置器(deallocate内存回收函数和reallocate内存扩充函数)

deallocate内存回收函数

deallocate函数的定义:

static void deallocate(void* __p, size_t __n)
  {
    if (__n > (size_t) _MAX_BYTES)
      malloc_alloc::deallocate(__p, __n);
    else {
      _Obj* __STL_VOLATILE*  __my_free_list
          = _S_free_list + _S_freelist_index(__n);
      _Obj* __q = (_Obj*)__p;

      // acquire lock
#       ifndef _NOTHREADS
      /*REFERENCED*/
      _Lock __lock_instance;
#       endif /* _NOTHREADS */
      __q -> _M_free_list_link = *__my_free_list;
      *__my_free_list = __q;
      // lock is released here
    }
  }

deallocate函数需要接收两个参数:一个是回收内存的起始地址,另一个是回收内存的大小。
如果回收内存的大小大于128字节,调用的是malloc_alloc::deallocate(__p, __n);,该函数所做的工作就只有free一个动作:
在这里插入图片描述
如果释放的内存小于128字节,只需把这块chunk块以头插的方式,插入对应自由链表_S_free_list的结点即可。在多线程环境下,对自由链表的操作是需要加锁的。

reallocate内存扩充/缩小函数

reallocate函数定义:

template <bool threads, int inst>
void*
__default_alloc_template<threads, inst>::reallocate(void* __p,
                                                    size_t __old_sz,
                                                    size_t __new_sz)
{
    void* __result;
    size_t __copy_sz;

    if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) {
        return(realloc(__p, __new_sz));
    }
    if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
    __result = allocate(__new_sz);
    __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
    memcpy(__result, __p, __copy_sz);
    deallocate(__p, __old_sz);
    return(__result);
}

如果新内存和旧内存的大小都大于128字节,直接调用库函数里的realloc函数。
如果新内存和旧内存提升后的大小需要的都是同样大小的chunk块,则不需要做任何改变。
否则就是申请一块新内存,比较新旧内存的大小,把小内存的内容往大内存拷,再释放旧内存,把新内存地址返回即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_200_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值