
《C 程序设计语言》 第八章 malloc 函数实现于内测管理
接下来是malloc函数,遍历各个区块如果尺寸大于需要尺寸就进行分割。正好相等就返回改区块
morecore函数就是像系统申请内存,并且先将其插入环链表中。由于多次像系统申请内测效率很低,所以morecore会制定一个最小申请区块的大小,提供给以后分割
最后就是free函数了,他用语将当前区块插入回环链表,并且如何其前后有相邻的区块进行合并。并且重现计算新区块的尺寸
发布日期:2021-05-07 23:35:37
浏览次数:18
分类:原创文章
本文共 4031 字,大约阅读时间需要 13 分钟。
这章举例实现了一个内存管理函数malloc 将系统以来的部分和非系统依赖的部分进行分离
malloc内部管理的内存区块实际上是一个环链表,用一个全局指针纪录上一次操作的节点,用户遍历时判断是否已经遍历一周。
每个链表节点又一个头部组成,纪录了下一个区块的地址和整个区块的尺寸
定义如下
typedef long Align;union header{ struct { union header * ptr; unsigned size; } s; Align x; };typedef union header Header;
Align是使得申明出来的区块具有字节对齐属性
接下来是malloc函数的实现
首先需要一个base 节点提供初始化使用
和一个全局指针指向上一次操作的节点
static Header * freep = NULL;static Header base;
接下来是malloc函数,遍历各个区块如果尺寸大于需要尺寸就进行分割。正好相等就返回改区块
如果遍历一周没有找到合适的尺寸就调用morecore函数像操作系统申请内存(该函数具有系统依赖)
void * malloc(unsigned nbytes){ Header *p, *prevp; Header *morecore(unsigned); unsigned nunits; nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; if((prevp = freep) == NULL){ base.s.ptr = freep = prevp = &base; base.s.size = 0; } for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) { if(p->s.size > nunits) { if(p->s.size == nunits) { prevp->s.ptr = p->s.ptr; } else { p->s.size -= nunits; p += p->s.size; p->s.size = nunits; } freep = prevp; return (void *) (p + 1); } if(p == freep) if((p = morecore(nunits)) == NULL) return NULL; }}
morecore函数就是像系统申请内存,并且先将其插入环链表中。由于多次像系统申请内测效率很低,所以morecore会制定一个最小申请区块的大小,提供给以后分割
#define NALLOC 1024Header * morecore(unsigned nunits){ char *cp, *sbrk(int); Header *up; void free(void *p); if(nunits < NALLOC) nunits = NALLOC; cp = sbrk(nunits * sizeof(Header)); if(cp == (char *)-1) return NULL; up = (Header *)cp; up->s.size = nunits; free((void *)(up + 1)); return freep;}
最后就是free函数了,他用语将当前区块插入回环链表,并且如何其前后有相邻的区块进行合并。并且重现计算新区块的尺寸
void free(void *ap){ Header *bp, *p; bp = (Header *)ap - 1; for(p = freep; !(bp > p && bp < p->s.ptr);p = p->s.ptr){ if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) break; } if(bp + bp->s.size == p->s.ptr){ bp->s.size += p->s.ptr->s.size; bp->s.ptr = p->s.ptr->s.ptr; }else bp->s.ptr = p->s.ptr; if(p + p->s.size == bp){ p->s.size += bp->s.size; p->s.ptr = bp->s.ptr; }else p->s.ptr = bp; freep = p;}
完整代码如下
#define NULL (0)typedef long Align;union header{ struct { union header * ptr; unsigned size; } s; Align x; };typedef union header Header;static Header * freep = NULL;static Header base;void * malloc(unsigned nbytes){ Header *p, *prevp; Header *morecore(unsigned); unsigned nunits; nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; if((prevp = freep) == NULL){ base.s.ptr = freep = prevp = &base; base.s.size = 0; } for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) { if(p->s.size > nunits) { if(p->s.size == nunits) { prevp->s.ptr = p->s.ptr; } else { p->s.size -= nunits; p += p->s.size; p->s.size = nunits; } freep = prevp; return (void *) (p + 1); } if(p == freep) if((p = morecore(nunits)) == NULL) return NULL; }}#define NALLOC 1024Header * morecore(unsigned nunits){ char *cp, *sbrk(int); Header *up; void free(void *p); if(nunits < NALLOC) nunits = NALLOC; cp = sbrk(nunits * sizeof(Header)); if(cp == (char *)-1) return NULL; up = (Header *)cp; up->s.size = nunits; free((void *)(up + 1)); return freep;}void free(void *ap){ Header *bp, *p; bp = (Header *)ap - 1; for(p = freep; !(bp > p && bp < p->s.ptr);p = p->s.ptr){ if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) break; } if(bp + bp->s.size == p->s.ptr){ bp->s.size += p->s.ptr->s.size; bp->s.ptr = p->s.ptr->s.ptr; }else bp->s.ptr = p->s.ptr; if(p + p->s.size == bp){ p->s.size += bp->s.size; p->s.ptr = bp->s.ptr; }else p->s.ptr = bp; freep = p;}
发表评论
最新留言
很好
[***.229.124.182]2025年04月07日 19时29分34秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Problem 330A - Cakeminator (思维)
2019-03-06
LeetCode75 颜色分类 (三路快排C++实现与应用)
2019-03-06
C语言+easyX图形库的推箱子实现
2019-03-06
调试vs2019代码的流程
2019-03-06
脱壳与加壳-加壳-6-代码实现加密导入表
2019-03-06
Typora配置PicGo时,提示Failed to fetch
2019-03-06
bcolz的新操作
2019-03-06
zmq的send
2019-03-06
delete对象时会自动调用类的析构函数
2019-03-06
POD类型
2019-03-06
const与常量,傻傻分不清楚~
2019-03-06
Head First设计模式——迭代器模式
2019-03-06
MongoDB版本及存储引擎区别
2019-03-06
shell echo单行和多行文字定向写入到文件中
2019-03-06
cmp命令
2019-03-06
Linux 磁盘管理(df fu fdisk mkfs mount)
2019-03-06
jQuery的事件绑定与触发 - 学习笔记
2019-03-06
Linux上TCP的几个内核参数调优
2019-03-06
记一次讲故事机器人的开发-我有故事,让机器人来读
2019-03-06
seo 回忆录百度基本概念(一)
2019-03-06