CSAPP:malloclab (显式空闲链表 LIFO+首次适配)

建议先学会书本的隐式空闲链表, 再学此显式空闲链表

显式空闲链表(双向空闲链表)的堆块格式

explict-list_block
使用显式空闲链表使得首次适配的分配时间从块总数(n)的线性时间减少到了空闲块数量(m)的线性时间:O(m) < O(n),其中m < n。释放块和合并块与隐式空闲链表一样都是O(1)。

显示空闲链表的格式

explict-list

宏marco

#define WSIZE 4
#define DSIZE 8
#define CHUNKSIZE (1 << 12)

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

/* Pack a size and allocated bit into a word */
#define PACK(size, alloc) ((size) | (alloc))

/* Read and write a word at address p */
#define GET(p) (*(unsigned int *)(p))
#define PUT(p, val) (*(unsigned int *)(p) = (val))

/* Read the size and allocated fields from address p */
#define GET_SIZE(p) (GET(p) & ~0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)

/* Given block ptr bp, compute address of its header and footer */
#define HDRP(bp) ((char *)(bp) - WSIZE)
#define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)


/* Given block ptr bp, compute address of next and previous blocks */
#define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE)))
#define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE)))

#define NEXT_NODEPTR(bp) ((char *)(bp) + WSIZE)
#define PREV_NODEPTR(bp) ((char *)(bp))

只有最后两句是新增的(其余与书本一致),PREV_NODEPTR(bp)表示PREV指针,NEXT_NODEPTR(bp)表示NEXT指针

函数原型

4个基本操作函数:

int mm_init(void);				// 创建带一个初始空闲块的堆
void *mm_malloc(size_t size);
void mm_free(void *ptr);
void *mm_realloc(void *ptr, size_t size);

其他函数:

static void *extend_heap(size_t words);		// 用一个新的空闲块扩展堆
static void *coalesce(void *bp);			// 合并
static void *find_fit(size_t asize);		// 首次适配
static void place(void *bp, size_t asize);	// 放置
void make_lifo(char *ptr);					// LIFO(新free的块放表头)
void fix_ptr(char *ptr);					// 调整prev、next指针

两个全局变量:

static char *heap_listp = NULL;
static char *root = NULL;			

函数详解

首先是mm_init():

int mm_init(void)
{
   
    /* Creat the initial empty heap */
    if ((heap_listp = mem_sbrk(6 * WSIZE)) == (void *)-1)
        return -1;

    PUT(heap_listp, 0);
    PUT(heap_listp + (1 * WSIZE), 0);   // Prev_nodeptr
    PUT(heap_listp + (2 * WSIZE), 0);   // Next_nodeptr
    PUT(heap_listp + (3 * WSIZE), PACK(DSIZE, 1));
    PUT(heap_listp + (4 * WSIZE), PACK(DSIZE, 1));
    PUT(heap_listp + (5 * WSIZE), PACK
  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值