ICS Malloc Lab: Writing a Dynamic Storage Allocator

这篇博客介绍了作者在ICS Malloc Lab中使用Splay伸展树实现动态存储分配器的过程。算法通过压缩数据结构减少空间浪费,利用头尾标志位记录分配状态,并优化了四字节块的处理。此外,还通过双向链表管理四字节块,以提高效率。文章详细阐述了算法设计和优化思想,并提供了调试辅助函数。
摘要由CSDN通过智能技术生成
/*
 * 首先我采用的是用splay伸展树来组织空白快,由当然每个块要有头和尾及左右儿子
 * 为了节省空间我用来自顶向下的splay这样可以省去father这一个,提高利用率
 * | head | leftson | rightson| ................| tail|
 * 当然splay树中的块都大于等于4字,最后优化的时候我把4字的块都取出来用
 * 双向链表串起来
 * 因为指针是双字的,为了提高利用率,因为总共分配的地址不多过2^32因此我们可以用
 * 一个相对地址来存储左右节点,这样head+left+right+tail 就被压缩到了4字。
 * 
 * 然后对于分配块通过书上提出的算法,我们只需要记录head即可,tail是可以省去的
 * 这样我们通过head中的倒数第二位记录前面一个块是否被分配
 *
 * 对于2个字的空白块,我只保留了他的head和tail 然后放在那里即可,合并时候用到
 * 他就可以了,然后我开辟了一个指针类似与记录信号性质我就记录2字的块,如果已经有
 * 2字的块了,则再释放一个2字的块就忽视。
 *
 * 进一步优化 对于四字的块 我用双向链表串起来
 *
 * 这样还是有点缺陷,99分。
 * 然后我想对于上一次申请的块,如果结尾还有p剩余,那么这次需要申请aszie大小,
 * 实际上我只申请了 asize-p,把p那块接上去就可以了。
 *
 * 以上就是我大致的算法和优化的思想
 * 实际中最麻烦的就是调试,printTree 和 printNode 是用来打印树和节点信息的
 * 代码中镶嵌有很多printf语句都是调试的时候查看信息留下的
 */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


#include "mm.h"
#include "memlib.h"


/* If you want debugging output, use the following macro.  When you hand
 * in, remove the #define DEBUG line. */
#define DEBUG
#ifdef DEBUG
# define dbg_printf(...) printf(__VA_ARGS__)
#else
# define dbg_printf(...)
#endif




/* do not CHANGE the following! */
#ifdef DRIVER
/* create aliases for driver tests */
#define malloc mm_malloc
#define free mm_free
#define realloc mm_realloc
#define calloc mm_calloc
#endif /* def DRIVER */


/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8


/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(p) (((size_t)(p) + (ALIGNMENT-1)) & ~0x7)


#define WSIZE 4
#define DSIZE 8
#define TSIZE 12
#define QSIZE 16
#define CHUNKSIZE (256)


#define BLOCK4 (4)
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))


#define PACK(size, alloc) ((size) | (alloc))
#define GET(p) (*(unsigned int *)(p))
#define PUT(p, val) (*(unsigned int *)(p) = (val))


#define GET_SIZE(p)  (GET(p) & ~0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)
#define GET_PRE_ALLOC(p) (GET(p) & 0x2)   //倒数第二位存放迁移块是否被释放的信息




#define HDRP(bp) ((char *)(bp) - WSIZE)
#define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)


#define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE)))
#define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE)))
//binary Tree
#define GET_LEFTSON(bp)  (GET( LEFTSON(bp)  ) ) 
#define GET_RIGHTSON(bp) (GET( RIGHTSON(bp) ) )


#define LEFTSON(bp)  ( (char *)(bp) )
#define RIGHTSON(bp) ( (char *)(bp) + WSIZE )




#define CHANGE32(bp) ( ( (char *)bp - Tnode))
#define CHANGE64(bp) ( (Tnode + bp))


#define CHECKMIN(bp, t) (GET_SIZE(HDRP(bp)) < GET_SIZE(HDRP(t))) || ((GET_SIZE(HDRP(bp)) == GET_SIZE(HDRP(t))) && CHANGE32(bp)<CHANGE32(t))
#define null (0)
//function
static void *extend_heap(size_t words);
static void *coalesce(void *bp);
static void place(void *bp, size_t asize);
static char * heap_listp;
static char * listp4;
static char * listp2;
static unsigned int root ;
static char * Tnode;
static char * LASTBLOCK= NULL;           // 最后一个块的脚步,用来判断是否需要跟新申请的块合并
static int ok = 0;
static void printTree(unsigned int root, unsigned int fa);
static void printNode(unsigned int root);
static void insert(void * bp);
static void move(void *bp);
static void splay(void * bp);
static void * find_fit(size_t asize);


//static int find(void * bp);
// 自顶向下的splay
static void splay(void * bp){
	   //printf("splay:(%p):\n",bp);
		//printf("splay root:%u\n",root);
	   if ( root == null )
				return ;
	// printTree(root, 0);
	// printf("splay after	\n");
		char * L = NULL;
		char * R = NULL;
		char * y = NULL;
		char * node = Tnode;
		PUT( LEFTSON(node), null );
		PUT( RIGHTSON(node), null );
		L = R = node;		
		void
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值