程序与技术分享: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

相关文章
|
2月前
|
存储 编译器 C语言
深入探索C语言动态内存分配:释放你的程序潜力
深入探索C语言动态内存分配:释放你的程序潜力
38 1
|
2月前
|
存储 程序员 C语言
【动态内存管理助力程序优化与性能飞升】(下)
【动态内存管理助力程序优化与性能飞升】
|
2月前
|
C语言
【动态内存管理助力程序优化与性能飞升】(中)
【动态内存管理助力程序优化与性能飞升】
|
2月前
|
存储 编译器 C语言
深入探索C语言动态内存分配:释放你的程序潜力
深入探索C语言动态内存分配:释放你的程序潜力
37 0
|
13天前
|
存储 Java C++
Java虚拟机(JVM)在执行Java程序时,会将其管理的内存划分为几个不同的区域
【6月更文挑战第24天】Java JVM管理内存分7区:程序计数器记录线程执行位置;虚拟机栈处理方法调用,每个线程有独立栈;本地方法栈服务native方法;Java堆存储所有对象实例,垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息;运行时常量池存储常量;直接内存不属于JVM规范,通过`java.nio`手动管理,不受GC直接影响。
22 5
|
13天前
|
算法 Java
垃圾回收机制(Garbage Collection,GC)是Java语言的一个重要特性,它自动管理程序运行过程中不再使用的内存空间。
【6月更文挑战第24天】Java的GC自动回收不再使用的内存,关注堆中的对象。通过标记-清除、复制、压缩和分代等算法识别无用对象。GC分为Minor、Major和Full类型,针对年轻代、老年代或整个堆进行回收。性能优化涉及算法选择和参数调整。
22 3
|
13天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
23 2
|
17天前
|
监控 算法 Java
Java虚拟机(JVM)使用多种垃圾回收算法来管理内存,以确保程序运行时不会因为内存不足而崩溃。
【6月更文挑战第20天】Java JVM运用多种GC算法,如标记-清除、复制、标记-压缩、分代收集、增量收集、并行收集和并发标记,以自动化内存管理,防止因内存耗尽导致的程序崩溃。这些算法各有优劣,适应不同的性能和资源需求。垃圾回收旨在避免手动内存管理,简化编程。当遇到内存泄漏,可以借助VisualVM、JConsole或MAT等工具监测内存、生成堆转储,分析引用链并定位泄漏源,从而解决问题。
26 4
|
18天前
|
编译器
程序的内存模型\栈区
程序的内存模型\栈区
22 4
|
18天前
|
C语言 C++
程序的内存模型\全局区
程序的内存模型\全局区
10 2