现在的位置: 首页 > 综合 > 正文

动态分配

2019年04月19日 ⁄ 综合 ⁄ 共 3115字 ⁄ 字号 评论关闭

http://haixiaoyang.wordpress.com/category/design/

static char* mem_start_brk;
static char* mem_brk;
static char* mem_max_brk;

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

#define PACK(size, alloc)	((size) | (alloc))
#define GET(p)				(*(size_t *)(p))
#define PUT(p, val)			(*(size_t *)(p) = (val))
#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)
#define NEXT_BLKP(bp)		((char*)(bp) + GET_SIZE((char*)(bp) - WSIZE))
#define PREV_BLKP(bp)		((char*)(bp) - GET_SIZE((char*)(bp) - DSIZE))

void mem_init(int size)
{
	mem_start_brk = malloc(size);
	mem_brk = mem_start_brk;
	mem_max_brk = mem_start_brk + size;
}

void* mem_sbrk(int incr)
{
	if (incr < 0 || mem_brk + incr > mem_max_brk)
		return (void*)-1;

	char* pRet = mem_brk;
	mem_brk += incr;

	return pRet;
}

static void* find_fit(size_t asize)
{
	char* pIter = mem_start_brk + WSIZE;
	while (pIter < mem_brk)
	{
		if (GET_SIZE(HDRP(pIter-WSIZE)) >= asize)//没有判别是否空闲块
			return pIter - WSIZE;

		pIter = NEXT_BLKP(pIter);
	}

	return NULL;
}

static void place(void* bp, size_t asize)
{
	size_t lftSize = GET_SIZE(bp) - asize;
	PUT(bp, PACK(asize, 1));
	PUT(bp + asize - WSIZE, PACK(asize, 1));

	if (lftSize == 0) return;

	char* pNew = bp + asize;//分割之后,要将后面的块设为空块
	PUT(pNew, PACK(lftSize, 0));
	PUT(bp + lftSize - WSIZE, PACK(lftSize, 0));
}

void* extend_heap(size_t words);
static void* coalesce(void* bp);

static void* extend_heap(size_t words)
{
	void* bp;
	size_t size;

	size = (words%2) ? (words + 1)*WSIZE : words * WSIZE;
	if ((int)(bp = mem_sbrk(size)) < 0)
		return NULL;

	PUT(HDRP(bp), PACK(size, 0));
	PUT(FTRP(bp), PACK(size, 0));
	PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1));

	return coalesce(bp);
}

static void* coalesce(void* bp)
{
	size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
	size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
	size_t size = GET_SIZE(HDRP(bp));

	if (prev_alloc && next_alloc)
		return bp;
	else if (prev_alloc && !next_alloc)
	{
		size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
		PUT(HDRP(bp), PACK(size, 0));
		PUT(FTRP(bp), PACK(size, 0));
		return bp;
	}
	else if (!prev_alloc && next_alloc)
	{
		size += GET_SIZE(HDRP(PREV_BLKP(bp)));
		PUT(FTRP(bp), PACK(size, 0));
		PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));

		return HDRP(PREV_BLKP(bp));
	}
	else
	{
		size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp)));
		PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
		PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));

		return HDRP(PREV_BLKP(bp));
	}
}

/////////////////////////// service functions /////////////////////////////
int mm_init();
void mm_free(void* bp);
void* mm_malloc(size_t size);
///////////////////////////////////////////////////////////////////////////

int mm_init()
{
	void* heap_listp;
	if (NULL == (heap_listp = mem_sbrk(4*WSIZE)))
		return -1;

	PUT(heap_listp, 0);
	PUT(heap_listp+WSIZE, PACK(OVERHEAD, 1));
	PUT(heap_listp+DSIZE, PACK(OVERHEAD, 1));
	PUT(heap_listp+WSIZE+DSIZE, PACK(0, 1));
	heap_listp += DSIZE;

	if (extend_heap(CHUNKSIZE/WSIZE) == NULL)
		return -1;
	return 0;
}

void mm_free(void* bp)
{
	size_t size = GET_SIZE(HDRP(bp));

	PUT(HDRP(bp), PACK(size, 0));
	PUT(FTRP(bp), PACK(size, 0));
	coalesce(bp);
}

void* mm_malloc(size_t size)
{
	size_t asize;
	char* bp;

	if (size <= 0)
		return NULL;

	if (size <= DSIZE)
		asize = DSIZE + OVERHEAD;
	else 
		asize = DSIZE * ((size + OVERHEAD + DSIZE - 1)/DSIZE);

	if (NULL != (bp = find_fit(asize)))
	{
		place(bp, asize);
		return bp;
	}

	size_t extendsize = max(asize, CHUNKSIZE);
	if (NULL == (bp = extend_heap(extendsize)))
		return NULL;

	place(bp, asize);
	return bp;
}
【上篇】
【下篇】

抱歉!评论已关闭.