用C语言实现的简易内存池
来源:互联网 发布:ubuntu 创建文件权限 编辑:程序博客网 时间:2024/05/17 22:50
这套内存池代码其实是我前不久刚刚进公司时,我的师傅安排给我的一个“作业”,可能目的是试探一下我的Coding能力,看看我的编码风格吧。现在把它写在这里和大家分享,这个代码并不是多么高效的内存池,只是作为一个简单的练习,开拓自己的思维,锻炼自己的链表编程能力。所以如果有人想找高效代码用在项目里,我建议还是使用开源的框架比较好。代码如果有BUG请指教,本人小白,大牛勿喷!
内存池的使用背景:
1.使用malloc系统函数分配内存虽然很方便,但是很容易产生碎片。
2.为了使关键模块在需要内存时,避免获取不到内存的麻烦。关键模块创建时,可以预先占用模块所需要的最大 内存,由模块内自行分配释放。
3.采用预占内存方式的模块,可以明确确定该模块所需要的内存资源大小。有利于硬件资源的确定。
我的编程思想是建立一个内存池结构体,存储内存池的信息,包括内存块数量、大小、已使用数量、起始地址、终止地址、指向第一个节点的链表指针。
测试实例
内存池的使用背景:
1.使用malloc系统函数分配内存虽然很方便,但是很容易产生碎片。
2.为了使关键模块在需要内存时,避免获取不到内存的麻烦。关键模块创建时,可以预先占用模块所需要的最大 内存,由模块内自行分配释放。
3.采用预占内存方式的模块,可以明确确定该模块所需要的内存资源大小。有利于硬件资源的确定。
我的编程思想是建立一个内存池结构体,存储内存池的信息,包括内存块数量、大小、已使用数量、起始地址、终止地址、指向第一个节点的链表指针。
注释中的所谓节点也是一个结构体,包含内存块指针,节点链表指针。分配内存块时,检测下池中是否有空闲,有则分配,并从池中删去节点,直到释放内存块时再插入链表。
使用完内存池后,释放内存池。这套代码中避免了遍历操作,而且统一开辟、释放内存,可以有效提高效率。
代码如下:
头文件
#ifndef _POOL_H#define _POOL_H#include "stdlib.h"#include "stdio.h"#include "string.h"#define LEN sizeof(memblock)//内存块节点大小#define OPERA_OK 0//操作失败#define OPERA_ERR 1//操作成功//内存块节点typedef struct MEMBLOCK{char* pmem;//内存指针 MEMBLOCK *next;//指向下一节点的指针}memblock;//内存池节点typedef struct MEMPOOL{int cnt;//数量int usedcnt;//使用个数int blocksize;//内存块大小char* firstaddr;//起始地址char* lastaddr;//结束地址MEMBLOCK *firstblock;//指向下一节点的指针}mempool;/*********************************************@brief 创建n个节点的内存池链表*@param* num数量* blocksize 内存块大小*@return OPERA_OK/OPERA_ERR*@see*********************************************/mempool *CreatePool(int num, int blocksize);/*********************************************@brief 销毁内存池*@param* poolhead内存池指针*@return OPERA_OK/OPERA_ERR*@see*********************************************/int DestroyPool(mempool *poolhead);/*********************************************@brief 得到一个内存块*@param* poolhead内存池指针*@return 内存块地址*@see*********************************************/char *GetMemblock(mempool *poolhead);/*********************************************@brief 释放一个内存块*@param* pmem内存块地址* poolhead内存池指针*@return OPERA_OK/OPERA_ERR*@see*********************************************/int ReleaseMemblock(char* pmem, mempool *poolhead);#endif.c文件
#include "pool.h"/*********************************************@brief 创建n个节点的内存池链表*@param* num数量* blocksize 内存块大小*@return OPERA_OK/OPERA_ERR*@see*********************************************/ mempool *CreatePool(int num,int blocksize ){if(num<=0||blocksize<=0){printf("Create input err\n");return NULL;}//内存池指针分配内存mempool *poolhead=NULL;//内存池指针poolhead=(mempool*)malloc(sizeof(mempool));//池节点申请内存if (NULL==poolhead){printf("poolhead malloc err!\n");return NULL;}memset(poolhead,0,sizeof(mempool));//内存池指针部分初始化赋值,其他默认为0无需初始poolhead->cnt=num;poolhead->blocksize=blocksize;//定义链表操作临时指针memblock *p1 = NULL;//创建的新节点的地址memblock *p2 = NULL;char* block;//内存块指针int n = 0;//创建前链表的节点总数为0:空链表//分配第一个内存块p1 = ( memblock *) malloc (LEN);//开辟第一个新节点if (NULL == p1){printf("p1 %d malloc err!\n",n+1);return NULL;}memset(p1,0,LEN);block=(char*)malloc(blocksize);//开辟内存块if (NULL == block){printf("firstblock malloc err!\n");return NULL;}memset(block,0,blocksize);//*内存池,内存块初始化赋值p1->pmem=block;poolhead->firstaddr=block; p2 = p1;//如果节点开辟成功,则p2先把它的指针保存下来以备后用if(p1==NULL)//节点开辟不成功{printf ("\nCann't create it, try it again in a moment!\n");return NULL;}while(n <num){n += 1;//节点总数增加1个if(n == 1)//如果节点总数是1,则head指向刚创建的节点p1{poolhead->firstblock = p1;p2->next = NULL; //此时的p2就是p1,也就是p1->next指向NULL。}else{p2->next = p1;//指向上次下面刚刚开辟的新节点}p2 = p1;//把p1的地址给p2保留,然后p1产生新的节点p1 = ( memblock *) malloc (LEN);//开辟出新节点if (NULL == p1){printf("p1 %d malloc err!\n",n+1);return NULL;}memset(p1,0,LEN);block=(char*)malloc(blocksize);//开辟出新内存块if (NULL == block){printf("block %d malloc err!\n", n + 1);return NULL;}memset(block,0,blocksize);p1->pmem=block;}p2->next = NULL;//链表的最后一个节点指向NULLpoolhead->lastaddr=p2->pmem+blocksize;//内存池 末尾地址free(p1->pmem);free(p1);//跳出了while循环,释放p1 多余的那个空间p1 = NULL;return poolhead; //返回创建链表的头指针 } /******************************************** *@brief 销毁内存池 *@param * poolhead内存池指针 *@return OPERA_OK/OPERA_ERR *@see *********************************************/int DestroyPool(mempool *poolhead) { if(poolhead==NULL){return OPERA_ERR;}memblock *p1=poolhead->firstblock; memblock *p2=p1; while(p1!=NULL) { p2=p1; p1=p1->next; free(p2->pmem);p2->pmem=NULL; free(p2); } poolhead->firstblock=NULL;free(poolhead);poolhead = NULL;return OPERA_OK; } /*********************************************@brief 得到一个内存块*@param* poolhead内存池指针*@return 内存块地址*@see*********************************************/char *GetMemblock(mempool *poolhead){if(poolhead->usedcnt==poolhead->cnt){printf("GetMemblock ERR !Pool Full!\n");return NULL;}if (poolhead==NULL||poolhead->firstblock==NULL){printf("pool in err!\n");return NULL;}memblock* p=poolhead->firstblock;poolhead->firstblock = p->next;p->next = NULL;poolhead->usedcnt++;return p->pmem;}/*********************************************@brief 释放一个内存块*@param* pmem内存块地址* poolhead内存池指针*@return OPERA_OK/OPERA_ERR*@see*********************************************/int ReleaseMemblock(char* pmem, mempool *poolhead){if(pmem==NULL){printf("Realease Mem input ERR!\n");return OPERA_ERR;}memblock *ptemp = (memblock *)malloc(LEN);if (NULL == ptemp){printf("ptemp malloc err!\n");return OPERA_ERR;}ptemp->pmem = pmem;ptemp->next=poolhead->firstblock;poolhead->firstblock = ptemp;poolhead->usedcnt--;return OPERA_OK;}
测试实例
#include "pool.h"int main(){int ret = OPERA_OK;mempool *pool = NULL;pool = CreatePool(3, 1024);//建立内存池if (pool == NULL){printf("Creat ERR!\n");}else{printf("Creat OK!\n");}printf("内存池信息 块数量%d,块大小%d,使用个数%d,起始地址0x%p,终止地址0x%p\n", pool->cnt, pool->blocksize, pool->usedcnt, pool->firstaddr, pool->lastaddr);char *Mem1 = GetMemblock(pool);printf("得到内存块地址0x%p\n", Mem1);printf("内存池信息 块数量%d,块大小%d,使用个数%d,起始地址0x%p,终止地址0x%p\n", pool->cnt, pool->blocksize, pool->usedcnt, pool->firstaddr, pool->lastaddr);char *Mem2 = GetMemblock(pool);printf("得到内存块地址0x%p\n", Mem2);printf("内存池信息 块数量%d,块大小%d,使用个数%d,起始地址0x%p,终止地址0x%p\n", pool->cnt, pool->blocksize, pool->usedcnt, pool->firstaddr, pool->lastaddr);char *Mem3 = GetMemblock(pool);printf("得到内存块地址0x%p\n", Mem3);printf("内存池信息 块数量%d,块大小%d,使用个数%d,起始地址0x%p,终止地址0x%p\n", pool->cnt, pool->blocksize, pool->usedcnt, pool->firstaddr, pool->lastaddr);char *Mem4 = GetMemblock(pool);printf("得到内存块地址0x%p\n", Mem4);printf("内存池信息 块数量%d,块大小%d,使用个数%d,起始地址0x%p,终止地址0x%p\n", pool->cnt, pool->blocksize, pool->usedcnt, pool->firstaddr, pool->lastaddr);ReleaseMemblock(Mem2, pool);printf("释放第二个内存块0x%p\n", Mem2);printf("内存池信息 块数量%d,块大小%d,使用个数%d,起始地址0x%p,终止地址0x%p\n", pool->cnt, pool->blocksize, pool->usedcnt, pool->firstaddr, pool->lastaddr);char *Mem5 = GetMemblock(pool);printf("得到内存块地址0x%p\n", Mem5);printf("内存池信息 块数量%d,块大小%d,使用个数%d,起始地址0x%p,终止地址0x%p\n", pool->cnt, pool->blocksize, pool->usedcnt, pool->firstaddr, pool->lastaddr);ret = DestroyPool(pool);//销毁内存池if (ret == OPERA_ERR){printf("Destory ERR!\n");}else{printf("Destroy OK!\n");}system("pause");return 0;}
0 0
- 用C语言实现的简易内存池
- 简易内存池的实现
- c语言实现的简易窗口程序
- c语言简易五子棋的实现
- C语言实现简易的信贷系统
- 内存池的C语言实现
- 内存池的C语言实现
- c语言实现的内存池
- C语言实现简易三子棋
- C语言实现简易通讯录
- 【简易通讯录】-----C语言实现
- C语言实现简易通讯录
- C语言实现简易版三子棋
- 简易的字符串内存池实现
- C语言实现内存池
- C语言实现内存池
- c语言内存池实现
- C语言链表实现的简易学生成绩管理系统
- JProgressBar的使用
- Python基础(四)——条件语句
- 区别method和function
- Linux的文件系统
- 嵌入式Linux驱动工程师要求
- 用C语言实现的简易内存池
- android中常用的读取文件方法,你知道吗?
- hdu 1269 强连通图的判定
- [android开源]MyRichEditor实现详解
- B树与B+树的区别
- String.matches()的用法
- Flink如何用窗格来优化窗口
- Linux系统编程--信号及信号处理(一)
- 【DSP开发】【计算机视觉】TI 视觉软件开发套件ADAS