程序与技术分享:C内存池的实现

简介: 程序与技术分享:C内存池的实现

总体的设计思路:


首先按照内存块的大小申请N块大小的连续内存区域。


构造内存块的双向链表,有2种,一种是空闲链表;另外一种为已经使用的链表。该双向链表也是一块固定大小的内存区域,每个链表节点存储了当前内存块的地址、该节点上一个节点以及下一个节点。


#define ut_base(TYPE) \


struct { \


TYPE next; \


TYPE prev; \


}attribute((packed))


/**


define memory block struct _block


**//代码效果参考:http://www.jhylw.com.cn/542727747.html

**/

typedef struct _block{


char data;


ut_base(struct _block) base;


}attribute((packed)) block;


内存池中存储链表的起始地址、内存块的起始地址、空闲链表的节点数、空闲链表的开始节点以及结束节点、已使用链表的节点的开始节点以及结束节点。


typedef struct _mem_pool


{


unsigned int blockCount;


unsigned int blockSize;


unsigned int freeSize;


unsigned int freeCount;


struct _block freeH;


struct _block freeT;


struct _block usedH;


struct _block usedT;


struct _block pBlockHead;


char pDataHead;


}attribute((packed)) mem_pool;


mem_pool.h


#define increment 64


/**


define base list


**/


#define ut_base(TYPE) \


struct { \


TYPE next; \


TYPE prev; \


}attribute((packed))


/**


define memory block struct _block


*/


typedef struct _block{


char data;


ut_base(struct _block) base;


}attribute((packed)) block;


/**


define memory pool


**/


typedef struct _mem_pool


{


unsigned int blockCount;


unsigned int blockSize;


unsigned int freeSize;


unsigned int freeCount;


struct _block freeH;


struct _block freeT;


struct _block usedH;


struct _block usedT;


struct _block pBlockHead;


char pDataHead;


}attribute((packed)) mem_pool;


/*


init a memory pool


*/


int pool_init(int blockSize,int blockCount);


/*


add block to mem_pool


**/


int pool_block(size_t unitSize,int blockCount);


/**


alloc memory from memory pool


**/


char pool_alloc(size_t allocSize);


/**


recyc memory from memory pool


**/


int pool_recyc();


/**


free all memory to operation system


**/


void pool_free();


/*


prt all list of memory pool


**/


void pool_prt();


mem_pool.c


#include


#include


#include [span style="color: rgba(0, 0, 255, 1)">string.h>


#include "mem_pool.h"


static mem_pool pool;


int pool_init(int blockSize,int blockCount)


{


mem_pool mp=&pool;


int flag=0;


mp->blockCount=mp->freeCount=blockCount;


mp->blockSize=blockSize;


mp->freeH=mp->freeT=NULL;


mp->usedH=mp->usedT=NULL;


flag=pool_block(blockSize,blockCount);


if(flag>0){fprintf(stderr," pool_init error\n");return 1;}


return 0;


}


int pool_block(size_t unitSize,int blockCount)


{


mem_pool mp=&pool;


int i=0;


mp->pBlockHead=(block )malloc(sizeof(block)blockCount);


mp->pDataHead=(char )malloc(sizeof(char)unitSizeblockCount);


memset(mp->pDataHead,'\0',sizeof(char)unitSizeblockCount);


mp->blockCount=blockCount;


mp->freeSize=sizeof(char)unitSizeblockCount;


block bk=NULL;


for(;i

{


bk=(block )mp->pBlockHead+(sizeof(block)i);


char data=mp->pDataHead+(sizeof(char)unitSizei);


bk->base.next=NULL;


bk->base.prev=mp->freeT;


if(mp->freeH==NULL)


{


mp->freeH=mp->freeT=bk;


}


else


{


mp->freeT->base.next=bk;


mp->freeT=bk;


}


bk->data=data;


}


printf(" ---------------pool_block(size_t unitSize=%d,int blockCount=%d)--------------\n",unitSize,blockCount);


printf(" mp->freeH : %p,mp->freeH->base.prev : %p\n",mp->freeH,mp->freeH->base.prev);


printf(" mp->freeT : %p,mp->freeT->base.next : %p\n",mp->freeT,mp->freeT->base.next);


return 0;


}


char pool_alloc(size_t allocSize)


{


mem_pool mp=&pool;


int allocCount=0;


int i=0;


if(mp->freeT==NULL)


{


pool_init(mp->blockSize,mp->blockCount);


printf("\t execute pool_init() \n");


}


if((allocSize%(mp->blockSize))==0)


{


allocCount=allocSize/(mp->blockSize);


}


else


{


allocCount=allocSize/(mp->blockSize)+1;


}


block bk=mp->freeT;


for(;ifreeT->base.prev;


bk->base.prev=NULL;


bk->base.next=NULL;


memset(bk->data,'\0',mp->blockSize);


// printf(" %d,mp->freeT : %p,mp->freeT->base.prev :%p\n",i,mp->freeT,mp->freeT->base.prev);


if(mp->usedH==NULL)


{


mp->usedH=mp->usedT=bk;


mp->usedH->base.prev=NULL;


}


else


{


bk->base.prev=mp->usedT;


mp->usedT->base.next=bk;


mp->usedT=bk;


//printf("bk :%p,bk->base.prev :%p,bk->base.next :%p\n",bk,bk->base.prev,bk->base.next);


}


//memset(mp->usedT->data,'\0',mp->blockSize);


mp->freeT=prev;


//printf("mp->freeT : %p\n",mp->freeT);


bk=mp->freeT;


//printf(" %d,mp->freeT : %p\n",i,mp->freeT);


}


mp->freeT->base.next=NULL;


//mp->freeT=mp->pBlockHead+(sizeof(block)(mp->blockCount-allocCount));


mp->freeCount=mp->freeCount-allocCount;


mp->freeSize=(mp->blockSize)(mp->blockCount-allocCount);


//memset(mp->pDataHead+mp->freeSize,'\0',allocCount);


printf(" --------pool_alloc(size_t allocSize=%d)--------\n",allocSize);


printf(" mp->freeH = %p,mp->freeT = %p\n",mp->freeH,mp->freeT);


printf(" mp->usedH = %p,mp->usedT = %p\n",mp->usedH,mp->usedT);


return mp->pDataHead+(mp->freeSize);


}


void pool_prt()


{


mem_pool p=&pool;


block fr=p->freeH;


block us=p->usedH;


int i=0;


printf(" \t**free list->\n");


while(fr!=NULL)


{


printf("\t(current = %p,data=%p)",fr,fr->data);


printf(",prev = %p",fr->base.prev);


printf(",next = %p\n",fr->base.next);


// printf("\t ## :current->data =%p",fr->data);


// printf(",prev->data = %p",fr->base.prev->data);


// printf(",next->data = %p\n",fr->base.next->data);


fr=fr->base.next;


i++;


}


printf(" \tfreelist length = %d\n",i);


i=0;


printf(" \t p->freeH = %p,p->freeT = %p\n",p->freeH,p->freeT);


printf(" \t**used list->\n");


while(us!=NULL)


{


printf("\t(current = %p,data=%p",us,us->data);


printf(",prev = %p",us->base.prev);


printf(",next = %p\n",us->base.next);


// printf("\t ## :current->data =%p",us->data);


//printf(",prev->data = %p",us->base.prev->data);


//printf(",next->data = %p\n",us->base.next->data);


us=us->base.next;


i++;


}


printf(" \tusedlist length = %d\n",i);


printf(" \tp->usedH = %p,p->usedT = %p\n",p->usedH,p->usedT);


printf("\n");


}


void pool_free()


{


mem_pool p=&pool;


free(p->pBlockHead);


free(p->pDataHead);


p->pBlockHead=NULL;


p->pDataHead=NULL;


printf("\t mem_pool free \n");


}


int pool_recyc(size_t freeSize)


{


mem_pool mp=&pool;


int cyc=0,i=0;


if(freeSize>(mp->blockSizemp->blockCount))


{


fprintf(stderr," freeSize is over all memory size in memory pool\n");


return 1;


}


if((freeSize%mp->blockSize)==0)


{


cyc=freeSize/(mp->blockSize);


}


else


{


cyc=(freeSize/mp->blockSize)+1;


}


printf(" --------pool_recyc(size_t freeize=%d)--------\n",freeSize);


printf(" recyc block count = %d\n",cyc);


printf(" begin: mp->freeH = %p,mp->freeT = %p\n",mp->freeH,mp->freeT);


printf(" begin: mp->usedH = %p,mp->usedT = %p\n",mp->usedH,mp->usedT);


printf(" begin: mp->freeCount = %d,mp->freeSize = %d\n",mp->freeCount,mp->freeSize);


if(mp->usedH==NULL)


{


fprintf(stderr," all block is not used in memory pool\n");


return 1;


}


block cur=mp->usedT;


for(;i

{


//link a block to free list


block *prev=cur->base.prev;


mp->freeT->base.next=cur;


cur->base.prev=mp->freeT;


memset(cur->data,'\0',mp->blockSize);


mp->freeT=cur;


//mp->usedT=mp->//代码效果参考:http://www.jhylw.com.cn/091324271.html

usedT->base.prev;

cur=prev;


mp->usedT=prev;


//remove a block from used


}


if(cyc==(mp->blockCount-mp->freeCount))


{


mp->usedH=mp->usedT=NULL;


}


if(mp->usedT!=NULL)


{


if(mp->usedT==m

相关文章
|
4月前
|
安全 Linux Shell
Linux上执行内存中的脚本和程序
【9月更文挑战第3天】在 Linux 系统中,可以通过多种方式执行内存中的脚本和程序:一是使用 `eval` 命令直接执行内存中的脚本内容;二是利用管道将脚本内容传递给 `bash` 解释器执行;三是将编译好的程序复制到 `/dev/shm` 并执行。这些方法虽便捷,但也需谨慎操作以避免安全风险。
236 6
|
3月前
|
NoSQL 测试技术
内存程序崩溃
【10月更文挑战第13天】
148 62
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
65 1
|
2月前
|
存储 缓存 Java
结构体和类在内存管理方面的差异对程序性能有何影响?
【10月更文挑战第30天】结构体和类在内存管理方面的差异对程序性能有着重要的影响。在实际编程中,需要根据具体的应用场景和性能要求,合理地选择使用结构体或类,以优化程序的性能和内存使用效率。
|
3月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
182 21
|
4月前
|
C语言 Android开发 C++
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
本文介绍了使用MTuner软件进行Qt MinGW编译程序的内存泄漏检测的方法,提供了MTuner的下载链接和测试代码示例,并通过将Debug程序拖入MTuner来定位内存泄漏问题。
基于MTuner软件进行qt的mingw编译程序的内存泄漏检测
|
4月前
|
存储 运维
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
|
5月前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
5月前
|
监控 Java API
如何从 Java 程序中查找内存使用情况
【8月更文挑战第22天】
378 0
|
6月前
|
缓存 弹性计算 数据库
阿里云2核4G服务器支持多少人在线?程序效率、并发数、内存CPU性能、公网带宽多因素
2核4G云服务器支持的在线人数取决于多种因素:应用效率、并发数、内存、CPU、带宽、数据库性能、缓存策略、CDN和OSS使用,以及用户行为和系统优化。阿里云的ECS u1实例2核4G配置,适合轻量级应用,实际并发量需结合具体业务测试。
106 0
阿里云2核4G服务器支持多少人在线?程序效率、并发数、内存CPU性能、公网带宽多因素

热门文章

最新文章