malloc lab

本文深入分析了基于隐式空闲链表和立即边界标记合并的内存分配器。内容涵盖堆的结构,包括序言块、普通块和结尾块的详细描述,以及如何获取空闲块起始地址、地址访问操作、初始空闲链表的创建,同时讨论了释放和合并块的机制。
摘要由CSDN通过智能技术生成

首先对基于隐式空闲链表,使用立即边界标记合并方式实现的简单分配器进行分析。实验参考资料

隐式空闲链表的恒定形式如下图所示:
在这里插入图片描述
其结构为: 第一个字是不使用的填充字,使得双字的序言块(prologue block)边界对齐。这个特殊的序言块是一个8字节的分配块,仅由一个头部和一个脚部组成。序言块后面紧跟着零个或多个malloc创建free调用的普通块,在初始化时,这个块接近堆的大小。在堆的尾部是一个特殊的大小为零已分配的结尾块(epilogue block),只由一个头部组成。在初始化(mm_init)的时候,序言块、结尾块以及之间的大的空闲块(具有头部和尾部,是由extend_heap函数创建的)被创建,序言块永远不会释放。
(1)获得堆中空闲块的起始地址

void *mem_sbrk(int incr) {
   
	char *old_brk=mem_brk; 
	
	if((incr<0)||((mem_brk+incr)>mem_max_addr)) {
   
		errno=ENOMEM;
		fprintf(stderr,"ERROR: mem_sbrk failed. Ran out of memory...\n");
		return (void *) -1;
	}
	mem_brk+=incr;
	return (void *)old_brk;
}

(2)定义具体地址访问操作实现方法

/*创建基本常量和操作,宏函数的名字应该能体现出函数的行为是什么*/
#define WSIZE 4 //一个字的大小,四个字节
#define DSIZE 8 //分配器的返回的块是8字节对齐的,块就是一次分配的大小,例如malloc(3),将返回块的大小是8
#define CHUNKSIZE (1<<12) //最大的空闲块

#define MAX(x,y) ((x) > (y)? (x) : (y))

/*将头部或尾部中保存的块的大小和3位标记位进行合并*/
#define PACK(size,alloc) ((size)|(alloc))

/*从地址p读或者写一个四字节的量*/
#define GET(p) (*(unsigned int *) (p))
#define PUT(p,val) (*(unsigned int *) (p)=(val))

/*从地址p获得块的大小以及查看块是已分配还是空闲的*/
#define GET_SIZE(p) (GET(p) & -0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)

/*从空闲块(有效载荷)地址获得头部地址或者尾部地址*/
#define HDRP(bp) ((char *)(bp) - WSIZE)
#define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)//这里减DSIZE是因为加上GET_SIZE,多加了一个头部                                                                                         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是浩浩子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值