牛骨文教育服务平台(让学习变的简单)
博文笔记

一个简单的变长内存池

创建时间:2014-06-02 投稿人: 浏览次数:110
#define NODE_SIZE  (200)                    //每个node的大小
#define BASE_NODE_NUM (1024 * 1)  //初始分配大小
#define STEP_NODE_NUM (1024 * 1)   //每次递增大小

#include <string.h>

#pragma pack(1)

typedef struct _mem_node 
{ 
    unsigned int num;   //每次分配的内存区域的个数
	union
	{
		struct _mem_node *next; 
		char buf[NODE_SIZE];   //每个node的大小
	};

	_mem_node()
	{
		num = 0;
		memset(buf,0,sizeof(buf));
	};

}mem_node_t, *pmem_node_t; 

#pragma pack()

/* block信息*/ 
typedef struct _mem_block 
{ 
	mem_node_t *node_head; 
	mem_node_t *node_tail; 
	unsigned int node_num;       // block中node个数
	struct _mem_block *next;     //用于将每个block连接起来
}mem_block_t, *pmem_block_t; 

/*pool信息*/ 
typedef struct _mem_pool 
{ 
	mem_block_t* block_head;    //第一个block
	mem_block_t* block_tail;    //最后一个block
	mem_node_t*  free_head;      //空闲节点
	unsigned int block_num;     //block个数
	unsigned int free_num;      //空闲节点个数 
	unsigned int base_num;     //初始内存节点个数
	unsigned int step_num;     //每次内存增长节点个数
}mem_pool_t, *pmem_pool_t;


int InitMemPool(int base, int step); //初始化内存池
void DestroyMemPool(void);           //销毁内存池

void* AllocMem(unsigned int size);  //分配内存
void FreeMem(void* ptr);            //销毁内存


#include "MemoryTest.h"
#include "stdio.h"
#include <string.h> 
#include <stdlib.h> 
#include <math.h>

#define MEM_POOL_DEBUG 

/*add new memory block to our memory pool*/ 
static int AddMemBlock(int num); 
/* init the new block */ 
static int InitMemBlock(int num, mem_block_t *block); 
/* init free_list of the new block */ 
static int InitFreeList(const mem_block_t *block); 

void print_mem_pool_info(void); 
//int mem_block_init(int base, int step); 

static mem_pool_t mem_pool; 
/*  mem_pool will have at least base blocks, 
and will increase steps a time if needed */ 
int InitMemPool(int base_num, int step_num) 
{       

	/* initiate mem_pool */ 
	memset(&mem_pool, 0, sizeof(mem_pool)); 
	mem_pool.base_num = base_num; 
	mem_pool.step_num = step_num; 
	/* add the base block(node of base count) into the memory pool */ 
	if(!AddMemBlock(base_num)) 
	{ 
		fprintf(stderr, "mem_pool_init::add_mem_block error/n"); 
		return 0; 
	} 
	return 1; 
} 

void DestroyMemPool(void) 
{ 
	mem_block_t *prev, *cur; 
	prev = NULL; 
	cur = mem_pool.block_head; 
	while(prev != NULL) 
	{ 
		prev = cur; 
		cur = cur->next; 
		free(cur->node_head); //逐个block中的node。
		free(prev);           //释放block自身
	} 

	memset(&mem_pool, 0, sizeof(mem_pool_t)); 
} 

void print_mem_pool_info(void) 
{ 
	int i; 
	mem_block_t *p; 
	if(mem_pool.block_head == NULL) 
	{ 
		fprintf(stderr, "memory pool has been created! 
"); 
		return; 
	} 
	printf("*************** memory pool information start *********************** 
"); 
	printf("block count: %4d 
", mem_pool.block_num); 
	printf("current free node count: %4d 
", mem_pool.free_num); 
	printf("base block size: %4d 
", mem_pool.base_num); 
	printf("increasing block size: %4d 
", mem_pool.step_num); 
	printf("the first block: %#x 
", mem_pool.block_head); 
	printf("the last block: %#x 
", mem_pool.block_tail); 
	printf("the first free node: %#x 

", mem_pool.free_head); 
	for(p = mem_pool.block_head, i = 0; p != NULL; p = p->next, i++) 
	{ 
		printf("-------------------block %4d--------------------------
", i+1); 
		printf("node count: %4d 
", p->node_num); 
		printf("the first node: %#x 
", p->node_head); 
		printf("the last node: %#x 
", p->node_tail); 
		printf("------------------------------------------------------
"); 
	} 
	printf("*****  memory pool information end  ****
"); 
} 

/* since the block size is constant, this function need no input parameter */ 
void* AllocMem(unsigned int size) 
{ 
	mem_node_t *p; 
	int num = (int)ceil((double)size / NODE_SIZE); //获得需要分配的节点数。
	/* no free node ready, attempt to allocate new free node */ 
	if(mem_pool.free_num < num) 
	{ 
		if(!AddMemBlock(mem_pool.step_num)) 
		{ 
			return NULL; 
		} 
	} 

	/* get free node from free_list */ 
	p = mem_pool.free_head; 
	p->num = num;
	mem_pool.free_head = ((mem_node_t*)(p + num - 1))->next; 
	/* decrease the free node count */ 
	mem_pool.free_num = mem_pool.free_num - num; 
	return p->buf; 
} 

void FreeMem(void *ptr) 
{ 
	mem_node_t* temp_node = (mem_node_t*)((char*)ptr - 4);

	if(ptr == NULL) 
	{ 
		return; 
	}       

	int num = temp_node->num;
	/* return the node to free_list */ 
	((mem_node_t*)(temp_node + num - 1))->next = mem_pool.free_head;  //插入到空闲链表头部

	mem_pool.free_head = temp_node; 
	/* increase the free node count */ 
	mem_pool.free_num = mem_pool.free_num + num; 
} 

/* add new memory block to our memory pool */ 
static int AddMemBlock(int num) 
{ 
	mem_block_t *block; 
	if( (block = (mem_block_t *)malloc(sizeof(mem_block_t))) == NULL) 
	{ 
		fprintf(stderr, "add_mem_block::malloc error/n"); 
		return 0; 
	}   

	memset(block, 0, sizeof(mem_block_t)); 
	if(!InitMemBlock(num, block)) 
	{ 
		fprintf(stderr, "mem_pool_init::mem_block_init error/n"); 
		return 0; 
	} 

	/* insert the new block in the head */ 
	block->next = mem_pool.block_head;  //采用前插法
	mem_pool.block_head = block; 
	if(mem_pool.block_tail == NULL) 
	{ 
		mem_pool.block_tail = block; 
	} 

	/* insert the new block into the free list */ 
	block->node_tail->next = mem_pool.free_head; 
	mem_pool.free_head = block->node_head;  //所有空闲的node链接起来,也是采用前插入法
	mem_pool.free_num += num; 
	/* increase the block count */ 
	mem_pool.block_num++;    
	return 1; 
} 
/* init the new block */ 
static int InitMemBlock(int num, mem_block_t *block) 
{ 
	int block_size; 
	mem_node_t* temp_node; 

	if(block == NULL) 
	{ 
		return 0; 
	} 

	block_size = num * sizeof(mem_node_t); 
	if( (temp_node = (mem_node_t *)malloc(block_size)) == NULL) 
	{ 
		fprintf(stderr, "mem_pool_init::malloc error/n"); 
		return 0; 
	} 
	memset(temp_node, 0, block_size); 
	memset(block, 0, sizeof(mem_block_t)); 
	block->node_num = num; 
	block->node_head = temp_node; 
	block->node_tail = temp_node + num - 1; 
	InitFreeList(block); 
	return 1; 
} 

/* init free_list of the new block */ 
static int InitFreeList(const mem_block_t *block) 
{ 
	mem_node_t *temp_node, *end; 
	if(block == NULL) 
	{ 
		return 0; 
	} 
	/* start initiating free list */ 
	end = block->node_tail; /* block_cnt > 0 */ 
	for(temp_node = block->node_head; temp_node < end; temp_node++) 
	{ 
		temp_node->next = (temp_node + 1); 
	} 
	temp_node->next = NULL; /* end->next = NULL */ 
	return 1; 
} 

#ifdef MEM_POOL_DEBUG 
#define ALLOC_COUNT 10 
void alloc_test(char *ptr[]) 
{ 
	int i, j; 
	for(i = 0; i < ALLOC_COUNT; i++) 
	{ 
		if( (ptr[i] = (char*)AllocMem(200)) == NULL) 
		{ 
			fprintf(stderr, "mem_alloc error
"); 
			return; 
		} 
		for(j = 0; j < ALLOC_COUNT; j++) 
		{ 
			ptr[i][j] = "a" + j; 
		} 
	} 
	for(i = 0; i < ALLOC_COUNT; i++) 
	{ 
		for(j = 0; j < ALLOC_COUNT; j++) 
		{ 
			printf("ptr[%d][%d]=%c  ", i, j, ptr[i][j]); 
		} 
		fputc("
", stdout); 
	} 
} 

int main(int argc, char *argv[]) 
{ 
	char *ptr1[ALLOC_COUNT], *ptr2[ALLOC_COUNT]; 
	printf("size = %d",sizeof(mem_node_t));

	if(!InitMemPool(BASE_NODE_NUM, STEP_NODE_NUM)) 
	{ 
		fprintf(stderr, "mem_pool_init error/n"); 
		return 1; 
	} 
	print_mem_pool_info(); 
	alloc_test(ptr1); 
	
	print_mem_pool_info(); 

	FreeMem((void*)ptr1[5]); 
	print_mem_pool_info(); 

	alloc_test(ptr2); 
	print_mem_pool_info(); 

	DestroyMemPool(); 
	
	if(!InitMemPool(BASE_NODE_NUM, STEP_NODE_NUM)) 
	{ 
		fprintf(stderr, "mem_pool_init error/n"); 
		return 1; 
	} 
	print_mem_pool_info(); 
	alloc_test(ptr1); 
	print_mem_pool_info(); 

	FreeMem(ptr1[5]); 

	print_mem_pool_info(); 
	alloc_test(ptr2); 
	print_mem_pool_info(); 
	DestroyMemPool(); 

	return 1;
} 

#endif /* #ifdef MEM_POOL_DEBUG */


声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。