经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
c语言实现内存池
来源:cnblogs  作者:yanghehuanglu  时间:2024/2/7 9:51:47  对本文有异议

概要

所谓内存池,顾名思义和线程池的设计原理是一样的,为了减少频繁申请释放内存而带来的资源消耗,减少释放内存后产生的内存碎片。

设计理念

为了方便管理内存池的设计通常是划分出一定数量的内存块,这些内存块的长度是一样的; 用户申请内存块时返回空闲的内存块地址,如果内存块使用完毕就释放该内存块,将该内存块置为空闲状态,放回到内存池,供以后使用。

内存池的设计核心几大模块:创建内存池,申请内存块,释放内存块,销毁内存池!

当然这只是常用的内存池设计,实际项目中可以根据需求设计不同的线程池:内存块的长度不一,可以提供自定义的内存块设计等兼容性更高的内存池。

本文只做内存池原理的讲解和实现最基础的内存池!更多的功能根据实际的需求进行扩展即可。

内存池的设计思路有很多,可以给予链表,数组,队列等进行设计,核心就是怎么存储内存块信息;本期是基于链表进行的内存池设计。

模块设计

内存池结构

内存块节点结构

  1. typedef struct MemoryBlock{
  2. void *data;//内存块起始地址
  3. struct MemoryBlock *next;//下一个内存块的地址
  4. }MemoryBlock;

内存池结构

  1. typedef struct MemoryPool{
  2. MemoryBlock *freeList;//空闲内存块链表
  3. MemoryBlock *usedList;//占用内存块链表
  4. int freeCount;//空闲内存块数量
  5. int usedCount;//占用内存块数量
  6. int blockCount;//内存块总数量
  7. }MemoryPool;

创建内存池

通过参数确定内存池中内存块的大小和数量,然后给每个内存块开辟空间,然后初始化空闲链表,占用链表,空闲数量,占用数量等

  1. MemoryPool *InitMemoryPool(int blockSize, int blockCount)
  2. {
  3. MemoryPool *pool = NULL;
  4. pool = (MemoryPool *)malloc(sizeof(MemoryPool));//为内存池分配空间
  5. pool->freeList = NULL;
  6. pool->usedList = NULL;
  7. for(int i = 0; i < blockCount; i++)
  8. {
  9. //创建内存块节点,插入到空闲链表
  10. MemoryBlock * block = (MemoryBlock *)malloc(sizeof(MemoryBlock));
  11. block->data = malloc(blockSize);
  12. block->next = pool->freeList;
  13. pool->freeList = block;
  14. }
  15. //初始化状态
  16. pool->freeCount = blockCount;
  17. pool->usedList = 0;
  18. pool->blockCount = blockCount;
  19. return pool;
  20. }

申请内存块

将内存池中空闲的内存块提供给用户使用,如果没有空闲内存块返回NULL。

  1. void *AllocateBlock(MemoryPool *pool)
  2. {
  3. if(pool->freeList == NULL || pool->freeCount == 0)
  4. return NULL;
  5. MemoryBlock *node = pool->freeList;
  6. //该内存块从空闲链表删除
  7. pool->freeList = node->next;
  8. //该内存块插入到占用链表
  9. node->next = pool->usedList;
  10. pool->usedList = node;
  11. //更新空闲,占用状态
  12. pool->usedCount++;
  13. pool->freeCount--;
  14. return node->data;
  15. }

 

释放内存块

将内存块放回到内存池

  1. void FreeBlock(MemoryPool *pool, void *data)
  2. {
  3. MemoryBlock *cur = pool->usedList;
  4. MemoryBlock *pre = NULL;
  5. //寻找给内存块的节点
  6. while(pre != NULL && cur->data != data)
  7. {
  8. pre = cur;
  9. cur = cur->next;
  10. }
  11. if(cur == NULL)
  12. return;
  13. //将该内存块从占用链表删除
  14. if(pre != NULL)
  15. pre->next = cur->next;
  16. else
  17. pool->usedList = cur->next;
  18. //将该内存块插入到空闲链表
  19. cur->next = pool->freeList;
  20. pool->freeList = cur;
  21. pool->freeCount++;
  22. pool->usedCount--;
  23. return;
  24. }

销毁内存池

销毁所有的内存块及分配过的空间

  1. void DestroyMemoryPool(MemoryPool *pool)
  2. {
  3. MemoryBlock *pre = NULL;
  4. //释放所有空闲内存块空间
  5. while(pool->freeList != NULL)
  6. {
  7. pre = pool->freeList;
  8. free(pool->freeList->data);
  9. pool->freeList = pool->freeList->next;
  10. free(pre);
  11. }
  12. //释放所有占用内存块空间
  13. while(pool->usedList != NULL)
  14. {
  15. pre = pool->usedList;
  16. free(pool->usedList->data);
  17. pool->usedList = pool->usedList->next;
  18. free(pre);
  19. }
  20. //释放内存池空间
  21. free(pool);
  22. pool->freeList = NULL;
  23. pool->usedList = NULL;
  24. pool->freeCount = 0;
  25. pool->usedCount = 0;
  26. return;
  27. }

至此一个最基础的内存池算是已经完成,在实际项目中可以在此基础上进行扩展;

main函数调用

  1. int main(void)
  2. {
  3. MemoryPool *pool;
  4. pool = InitMemoryPool(10, 5);
  5. int *str = (int *)AllocateBlock(pool);
  6. *str = 2;
  7. int *ptr = (int *)AllocateBlock(pool);
  8. *ptr = 3;
  9. printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);
  10. FreeBlock(pool, ptr);
  11. printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);
  12. DestroyMemoryPool(pool);
  13. return 0;
  14. }

 

原文链接:https://www.cnblogs.com/yhfs/p/18009559

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号