• 剖析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
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

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

  • 相关阅读:
    java中springBoot+oss基础使用
    【云原生】Prometheus Pushgateway使用详解
    lua协程
    基于矩阵分解模型的协同过滤理论概述(涉及到SVD,SVD++,TimeSVD++)
    【需求侧响应】综合能源中多种需求响应——弹性电价、可平移及可削减研究(Matlab代码实现)
    OSPF虚拟链路以及选路
    typescript中的类型type与接口interface
    服务治理--Eureka
    批量混剪系统视频闪闪批量剪辑:只需几段素材片段即可批量混剪大量成片,快速制作大量成片的秘密
    JAVA------基础篇
  • 原文地址:https://blog.csdn.net/weixin_43973403/article/details/126077951