一个简单的变长内存池
#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 */
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: C51学习笔记
- 下一篇: C51简介及Keil的使用