堆的空闲链表分配算法

//block descriptor
typede struct _heap_block_t
{
	enum
	{
		HEAP_BLOCK_FREE = 0xdeadbeef;
		HEAP_BLOCK_USED = 0xc001cafe;
	}type;
	
	unsigned int size;
	struct _heap_block_t *next;
	struct _heap_block_t *prev;
}heap_block_t;

typedef unsigned int size_t;

void bset(void *p, char c, size_t size)
{
	assert(p != NULL);
	
	int i = 0;
	for(i=0; itype != HEAP_BLOCK_USED)
	{
		return;
	}
	
	p->type = HEAP_BLOCK_FREE;
	
	heap_block_t *prev_blk = p->prev;
	if(prev_blk != NULL && prev_blk->type == HEAP_BLOCK_FREE)
	{
		prev_blk->next = p->next;
		prev_blk->size += (p->size + HEADER_SIZE);
		
		if(p->next != NULL)
		{
			p->next->prev = p->prev;
		}
		
		bset(p, 0, p->size);
		
		p = prev_blk;
	}
	
	heap_block_t *next_blk = p->next;
	
	if(next_blk != NULL && next_blk == HEAP_BLOCK_FREE)
	{
		p->next = next_blk->next;
		p->size += (next_blk->size + HEADER_SIZE);
		if(next_blk->next != NULL)
		{
			next_blk->next->prev = p->prev;
		}
		
		bset(p, 0, p->size);
	}
}

void *malloc(size_t size)
{
	if(size == 0)
	{
		return NULL;
	}

	heap_block_t *p = list_head;
	
	while(p != NULL)
	{
		if(p->type == HEAP_BLOCK_FREE)
		{
			if((size > p->size + HEADER_SIZE) && (size < p->size + HEADER_SIZE*2))
			{
				//just the right size
				p->type = HEAP_BLOCK_USED;
				return (void *)((char *)p + HEADER_SIZE);
			}
			else if(size > p->size + HEADER_SIZE*2)
			{
				//we split it
				heap_block_t *nb = (heap_block_t *)(size + HEADER_SIZE);
				nb->next = p->next;
				nb->prev = p;
				nb->type = HEAP_BLOCK_FREE;
				nb->size = p->size - (size + HEADER_SIZE);
				
				if(p->next->prev)
				{
					p->next->prev = nb;
				}
				
				p->next = nb;
				p->type = HEAP_BLOCK_USED;
				p->size = size;
				
				return (void *)((char *)p + HEADER_SIZE);
			}
			//size < p->size + HEADER_SIZE
			//continue
			else
			{
				p = p->next;
			}
		}
		else
		{
			p = p->next;
		}
	}
	
	//we can't find any free block 
	return NULL;
}

int mini_crt_heap_init()
{
	void *base = NULL;
	unsigned int heap_size = 1024*1024*32;
	
	base = (void *)brk(0);
	void *end = base + heap_size;
	end = (void *)brk(end);
	
	if(!end) return 0;
	
	list_head = (heap_block_t *)base;
	
	list_head->size = heap_size;
	list_head->type = HEAP_BLOCK_FREE;
	list_head->next = list_head->prev = NULL;
	
	
	return 1;
}
修改了<程序员的自我修养中>中的代码,那里堆的分配代码有问题。

你可能感兴趣的:(algo/data,struct)