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