STL内存管理的C实现

简介: //STL 内存管理器的C实现 #include stdio.h> #include stdlib.h> #define __ALIGN 8    //小型区块上调边界 #define __MAX_BYTES 128    //小型区块大小的上限 ...
  1. //STL 内存管理器的C实现

  2. #include stdio.h>
  3. #include stdlib.h>

  4. #define __ALIGN 8    //小型区块上调边界
  5. #define __MAX_BYTES 128    //小型区块大小的上限
  6. #define __NFREELISTS (__ALIGN/__MAX_BYTES)    //free-lists的个数

  7. typedef union obj{
  8.     union obj *free_list_link;
  9.     char client_data[1];
  10. }obj;
  11. obj *free_list[__NFREELISTS];
  12. char *start_free;    //mempool开始位置
  13. char *end_free;    //mempool结束位置
  14. size_t heapsize;

  15. size_t ROUND_UP(size_t bytes);
  16. size_t FREELIST_INDEX(size_t bytes);
  17. void *stl_malloc(size_t nbytes);
  18. void stl_free(void *p, size_t nbytes);
  19. void *refill(size_t n);
  20. char *chunk_alloc(size_t bytes, size_t *nobjs);


  21. int main(){
  22.     int len= 65;
  23.     void *ptr = stl_malloc(len);
  24.     printf("%p\n", ptr);
  25.     stl_free(ptr, len);
  26.     return 0;
  27. }

  28. //将bytes上调到__ALIGN的倍数
  29. size_t ROUND_UP(size_t bytes){
  30.     return ((bytes + __ALIGN - 1) & ~(__ALIGN - 1));
  31. }
  32. //返回bytes所对应的freelist索引号
  33. size_t FREELIST_INDEX(size_t bytes){
  34.     return ((bytes + __ALIGN - 1) / __ALIGN - 1);
  35. }
  36. void *stl_malloc(size_t nbytes){
  37.     if(nbytes > 128){
  38.         return malloc(nbytes);
  39.     }
  40.     obj **my_free_list;
  41.     obj *result;
  42.     my_free_list = free_list + FREELIST_INDEX(nbytes);
  43.     result = *my_free_list;
  44.     if(result == NULL){
  45.         void *r = refill(ROUND_UP(nbytes));
  46.         return r;
  47.     }
  48.     //取出空闲块
  49.     *my_free_list = result->free_list_link;
  50.     return result;
  51. }
  52. void stl_free(void *p, size_t nbytes){
  53.     obj *q = (obj *)p;
  54.     obj **my_free_list;
  55.     if(nbytes > (size_t)__MAX_BYTES){
  56.         free(p);
  57.         return;
  58.     }
  59.     my_free_list = free_list + FREELIST_INDEX(nbytes);
  60.     q->free_list_link = *my_free_list;
  61.     *my_free_list = q;
  62. }
  63. void *refill(size_t n){
  64.     //默认从内存池取得20个块,多个块构成一个chunk
  65.     size_t nobjs = 20;    //-结果参数
  66.     char *chunk = chunk_alloc(n, &nobjs);    
  67.     if(!chunk){
  68.         return NULL;
  69.     }
  70.     obj **my_free_list;
  71.     obj *result, *cur_obj, *next_obj;
  72.     int i;
  73.     //内存池空间告急仅返回一个块,则直接返回给用户
  74.     if(nobjs == 1){
  75.         return chunk;
  76.     }
  77.     //否则准备向free_list中纳入新的节点
  78.     my_free_list = free_list + FREELIST_INDEX(n);
  79.     //以下在chunk的连续空间上建立free_list
  80.     result = (obj *)chunk;    //此块返回给用户
  81.     *my_free_list = next_obj = (obj *)(chunk + n);
  82.     for(i = 1; ; i++){
  83.         cur_obj = next_obj;
  84.         next_obj = (obj *)((char *)next_obj + n);
  85.         if(nobjs - 1 == i){
  86.             cur_obj->free_list_link = NULL;
  87.             break;
  88.         }else{
  89.             cur_obj->free_list_link = next_obj;    
  90.         }
  91.     }
  92.     return result;
  93. }
  94. //从内存池取连续的块空间
  95. char *chunk_alloc(size_t bytes, size_t *nobjs){
  96.     char *result;
  97.     size_t total_bytes = bytes * (*nobjs);    //要求的字节数
  98.     size_t bytes_left = end_free - start_free;    //

  99.     //内存池空间宽裕
  100.     if(bytes_left >= total_bytes){
  101.         result = start_free;
  102.         start_free += total_bytes;
  103.         return result;
  104.     }else if(bytes_left >= bytes){
  105.         //不够分配全部的,但是还可以分配一个或多个块
  106.         *nobjs = bytes_left/bytes;
  107.         total_bytes = *nobjs * bytes;
  108.         result = start_free;
  109.         start_free += total_bytes;
  110.         return result;
  111.     }else{
  112.         //内存池黔驴技穷了,连一个块的空间都没有了
  113.         size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heapsize >> 4);
  114.         if(bytes_left > 0){
  115.             //内存池中还有一些零头,先配给适当的free-list
  116.             obj **my_free_list = free_list + FREELIST_INDEX(bytes_left);
  117.             ((obj *)start_free)->free_list_link = *my_free_list;
  118.             *my_free_list = (obj *)start_free;
  119.         }
  120.         start_free = (char *)malloc(bytes_to_get);
  121.         if(start_free == NULL){
  122.             //看看更大块的free_list有无可用块
  123.             int i;
  124.             obj **my_free_list, *p;
  125.             for(i = bytes; i = __MAX_BYTES; i += __ALIGN){
  126.                 my_free_list = free_list + FREELIST_INDEX(i);
  127.                 p = *my_free_list;
  128.                 if(p){
  129.                     *my_free_list = p->free_list_link;
  130.                     start_free = (char *)p;
  131.                     end_free = start_free + i;
  132.                     //递归调用自己,按新的状态重新分配,并修正nobjs;
  133.                     return chunk_alloc(bytes, nobjs);
  134.                 }
  135.             }
  136.             //实在没有空间了
  137.             end_free = 0;
  138.             return NULL;
  139.         }
  140.         heapsize += bytes_to_get;
  141.         end_free = start_free + bytes_to_get;
  142.         return chunk_alloc(bytes, nobjs);
  143.     }
  144.     
  145. }
目录
相关文章
|
数据采集 自然语言处理 大数据
​「Python大数据」LDA主题分析模型
使用Python进行文本聚类,流程包括读取VOC数据、jieba分词、去除停用词,应用LDA模型(n_components=5)进行主题分析,并通过pyLDAvis生成可视化HTML。关键代码涉及数据预处理、CountVectorizer、LatentDirichletAllocation以及HTML文件的本地化处理。停用词和业务术语列表用于优化分词效果。
823 0
​「Python大数据」LDA主题分析模型
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
187 2
anaconda下载安装,镜像源配置修改及虚拟环境的创建
这篇文章介绍了Anaconda的下载安装过程,包括Anaconda的简介、安装步骤、配置修改、创建虚拟环境以及一些常用命令的使用方法。文章还提供了如何修改conda的镜像源为国内镜像源以加速下载的步骤。
anaconda下载安装,镜像源配置修改及虚拟环境的创建
|
1天前
|
云安全 人工智能 自然语言处理
AI说的每一句话,都靠谱吗?
阿里云提供AI全栈安全能力,其中针对AI输入与输出环节的安全合规挑战,我们构建了“开箱即用”与“按需增强”相结合的多层次、可配置的内容安全机制。
|
5天前
|
存储 人工智能 安全
AI 越智能,数据越危险?
阿里云提供AI全栈安全能力,为客户构建全链路数据保护体系,让企业敢用、能用、放心用
|
8天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
3天前
|
消息中间件 安全 NoSQL
阿里云通过中国信通院首批安全可信中间件评估
近日,由中国信通院主办的 2025(第五届)数字化转型发展大会在京举行。会上,“阿里云应用服务器软件 AliEE”、“消息队列软件 RocketMQ”、“云数据库 Tair”三款产品成功通过中国信通院“安全可信中间件”系列评估,成为首批获此认证的中间件产品。此次评估覆盖安全可信要求、功能完备性、安全防护能力、性能表现、可靠性与可维护性等核心指标,标志着阿里云中间件产品在多架构适配与安全能力上达到行业领先水平。
301 192