使用C語言實現(xiàn)內存池的示例代碼
概要
所謂內存池,顧名思義和線程池的設計原理是一樣的,為了減少頻繁申請釋放內存而帶來的資源消耗,減少釋放內存后產生的內存碎片。
設計理念
為了方便管理內存池的設計通常是劃分出一定數(shù)量的內存塊,這些內存塊的長度是一樣的; 用戶申請內存塊時返回空閑的內存塊地址,如果內存塊使用完畢就釋放該內存塊,將該內存塊置為空閑狀態(tài),放回到內存池,供以后使用。
內存池的設計核心幾大模塊:創(chuàng)建內存池,申請內存塊,釋放內存塊,銷毀內存池!
當然這只是常用的內存池設計,實際項目中可以根據(jù)需求設計不同的線程池:內存塊的長度不一,可以提供自定義的內存塊設計等兼容性更高的內存池。
本文只做內存池原理的講解和實現(xiàn)最基礎的內存池!更多的功能根據(jù)實際的需求進行擴展即可。
內存池的設計思路有很多,可以給予鏈表,數(shù)組,隊列等進行設計,核心就是怎么存儲內存塊信息;本期是基于鏈表進行的內存池設計。
模塊設計
內存池結構
內存塊節(jié)點結構
typedef struct MemoryBlock{
void *data;//內存塊起始地址
struct MemoryBlock *next;//下一個內存塊的地址
}MemoryBlock;內存池結構
typedef struct MemoryPool{
MemoryBlock *freeList;//空閑內存塊鏈表
MemoryBlock *usedList;//占用內存塊鏈表
int freeCount;//空閑內存塊數(shù)量
int usedCount;//占用內存塊數(shù)量
int blockCount;//內存塊總數(shù)量
}MemoryPool;創(chuàng)建內存池
通過參數(shù)確定內存池中內存塊的大小和數(shù)量,然后給每個內存塊開辟空間,然后初始化空閑鏈表,占用鏈表,空閑數(shù)量,占用數(shù)量等
MemoryPool *InitMemoryPool(int blockSize, int blockCount)
{
MemoryPool *pool = NULL;
pool = (MemoryPool *)malloc(sizeof(MemoryPool));//為內存池分配空間
pool->freeList = NULL;
pool->usedList = NULL;
for(int i = 0; i < blockCount; i++)
{
//創(chuàng)建內存塊節(jié)點,插入到空閑鏈表
MemoryBlock * block = (MemoryBlock *)malloc(sizeof(MemoryBlock));
block->data = malloc(blockSize);
block->next = pool->freeList;
pool->freeList = block;
}
//初始化狀態(tài)
pool->freeCount = blockCount;
pool->usedList = 0;
pool->blockCount = blockCount;
return pool;
}申請內存塊
將內存池中空閑的內存塊提供給用戶使用,如果沒有空閑內存塊返回NULL。
void *AllocateBlock(MemoryPool *pool)
{
if(pool->freeList == NULL || pool->freeCount == 0)
return NULL;
MemoryBlock *node = pool->freeList;
//該內存塊從空閑鏈表刪除
pool->freeList = node->next;
//該內存塊插入到占用鏈表
node->next = pool->usedList;
pool->usedList = node;
//更新空閑,占用狀態(tài)
pool->usedCount++;
pool->freeCount--;
return node->data;
}釋放內存塊
將內存塊放回到內存池
void FreeBlock(MemoryPool *pool, void *data)
{
MemoryBlock *cur = pool->usedList;
MemoryBlock *pre = NULL;
//尋找給內存塊的節(jié)點
while(pre != NULL && cur->data != data)
{
pre = cur;
cur = cur->next;
}
if(cur == NULL)
return;
//將該內存塊從占用鏈表刪除
if(pre != NULL)
pre->next = cur->next;
else
pool->usedList = cur->next;
//將該內存塊插入到空閑鏈表
cur->next = pool->freeList;
pool->freeList = cur;
pool->freeCount++;
pool->usedCount--;
return;
}銷毀內存池
銷毀所有的內存塊及分配過的空間
void DestroyMemoryPool(MemoryPool *pool)
{
MemoryBlock *pre = NULL;
//釋放所有空閑內存塊空間
while(pool->freeList != NULL)
{
pre = pool->freeList;
free(pool->freeList->data);
pool->freeList = pool->freeList->next;
free(pre);
}
//釋放所有占用內存塊空間
while(pool->usedList != NULL)
{
pre = pool->usedList;
free(pool->usedList->data);
pool->usedList = pool->usedList->next;
free(pre);
}
//釋放內存池空間
free(pool);
pool->freeList = NULL;
pool->usedList = NULL;
pool->freeCount = 0;
pool->usedCount = 0;
return;
}至此一個最基礎的內存池算是已經完成,在實際項目中可以在此基礎上進行擴展;
main函數(shù)調用
int main(void)
{
MemoryPool *pool;
pool = InitMemoryPool(10, 5);
int *str = (int *)AllocateBlock(pool);
*str = 2;
int *ptr = (int *)AllocateBlock(pool);
*ptr = 3;
printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);
FreeBlock(pool, ptr);
printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);
DestroyMemoryPool(pool);
return 0;
}到此這篇關于使用C語言實現(xiàn)內存池的示例代碼的文章就介紹到這了,更多相關C語言實現(xiàn)內存池內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++?Qt開發(fā)之運用QJSON模塊解析數(shù)據(jù)
JSON(JavaScript?Object?Notation)是一種輕量級的數(shù)據(jù)交換格式,它易于人閱讀和編寫,也易于機器解析和生成,本文主要介紹了Qt如何運用QJson組件的實現(xiàn)對JSON文本的靈活解析功能,需要的可以參考下2024-01-01
C++ 隨機數(shù)字以及隨機數(shù)字加字母生成的案例
這篇文章主要介紹了C++ 隨機數(shù)字以及隨機數(shù)字加字母生成的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12

