内存池的C++实现。

原文:http://blog.csdn.net/gisfarmer/article/details/4099499

最近在学习c++程序性能优化,读到内存池部分。自己动手写了一个,小小测试了一下应该没有问题。

内存块MemoryBlock声明文件

[cpp]  view plain copy
  1. #pragma once  
  2. #define USHORT unsigned short  
  3. #define ULONG unsigned long  
  4. #include <iostream>  
  5. using namespace std;  
  6. //内存块  
  7. struct MemoryBlock  
  8. {  
  9.     USHORT m_nSize;//可分配内存总大小  
  10.     USHORT m_nFree;//可分配内存单元数目  
  11.     USHORT m_nFirst;//第一个可用的内存单元位置  
  12.     MemoryBlock* m_pNext;//指向下一个内存块  
  13.     char m_data[1];  
  14.     void* operator new(size_t,const USHORT& sum,const USHORT& unit_size)  
  15.     {  
  16.         return ::operator new(sizeof(MemoryBlock)+sum*unit_size);//申请一个内存块空间  
  17.     }  
  18.     void operator delete(void* del,size_t)  
  19.     {  
  20.         ::operator delete(del);//删除内存块空间  
  21.     }  
  22.     MemoryBlock(const USHORT& sum,const USHORT& unit_size)  
  23.         :m_nSize(sum*unit_size),m_nFree(sum-1),m_nFirst(1),m_pNext(0)  
  24.     {  
  25.         char* pData=m_data;  
  26.         for(int i=1;i<sum;i++)//初始化1到sum-1指向  
  27.         {  
  28.             *reinterpret_cast<USHORT*>(pData)=i;  
  29.             pData+=unit_size;  
  30.         }  
  31.     }  
  32.     ~MemoryBlock(){}  
  33.   
  34. };  
  

内存池MemoryPool声明文件

[cpp]  view plain copy
  1. #pragma once  
  2. #include "MemoryBlock.h"  
  3.   
  4. //内存池 a very good memory manager  
  5. class MemoryPool  
  6. {  
  7. private:  
  8.     USHORT m_nUnitSize;//一个可分配单元的大小  
  9.     USHORT m_nInitSize;//第一个可分配空间数目  
  10.     USHORT m_nGrowSize;//新增的可分配空间数目  
  11.     MemoryBlock* m_pFirst;//指向第一个内存块  
  12. public:  
  13.     //单元大小,第一个内存块的可分配空间数目,第二个内存块之后的可分配空间数目  
  14.     MemoryPool(const USHORT& unit_size,const USHORT& init_size=2048,const USHORT& grow_size=1024);  
  15.     ~MemoryPool(void);  
  16.     void* Alloc();//分配内存  
  17.     void Free(void* pfree);//回收内存  
  18.     void FreeMemoryBlock(MemoryBlock *pblock);//销毁  
  19. };  

内存池MemoryPool实现文件

[cpp]  view plain copy
  1. #include "MemoryPool.h"  
  2. const USHORT MEMPOOL_ALIGNMENT=2;  
  3.   
  4. MemoryPool::MemoryPool(const USHORT &unit_size, const USHORT &init_size, const USHORT &grow_size)  
  5.     :m_pFirst(0),  
  6.      m_nInitSize(init_size),  
  7.      m_nGrowSize(grow_size)  
  8. {  
  9.     if(unit_size>4)  
  10.     {  
  11.         m_nUnitSize = (unit_size + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);  
  12.         //m_nUnitSize 取整到大于unit_size的最大的MEMPOOL_ALIGNMENT的倍数.  
  13.         //令人纠结的注释  
  14.     }  
  15.     else if(unit_size>=2)  
  16.         m_nUnitSize=4;  
  17.     else  
  18.         m_nUnitSize=2;  
  19. }  
  20.   
  21. void* MemoryPool::Alloc()  
  22. {  
  23.     if(!m_pFirst)//如果是第一次申请  
  24.     {  
  25.         MemoryBlock* pmb_first=new (m_nInitSize,m_nUnitSize)MemoryBlock(m_nInitSize,m_nUnitSize);//14日凌晨至此  
  26.         m_pFirst=pmb_first;  
  27.         return (void*)pmb_first->m_data;  
  28.     }  
  29.     MemoryBlock* pmb_block=m_pFirst;  
  30.     while(pmb_block&&pmb_block->m_nFree==0)//pmb_block没走到最后并且当前block没有可分配结点  
  31.     {  
  32.         pmb_block=pmb_block->m_pNext;//往后走吧。  
  33.     }  
  34.     if(pmb_block)//如果找到可分配结点的block  
  35.     {  
  36.         char* pfree=pmb_block->m_data+(pmb_block->m_nFirst*m_nUnitSize);  
  37.         pmb_block->m_nFirst=*((USHORT*)pfree);  
  38.         pmb_block->m_nFree--;//可分配节点自减  
  39.         return (void*)pfree;  
  40.     }  
  41.     else//如果找不到,此时pmb_block值为0  
  42.     {  
  43.         if(m_nGrowSize==NULL)  
  44.             return NULL;  
  45.         pmb_block=new (m_nGrowSize,m_nUnitSize)MemoryBlock(m_nGrowSize,m_nUnitSize);  
  46.         if(!pmb_block)//new不成功  
  47.             return NULL;  
  48.         pmb_block->m_pNext=m_pFirst;//把新建的block放到最前吧  
  49.         m_pFirst=pmb_block;  
  50.         return (void*)pmb_block->m_data;  
  51.     }  
  52. }  
  53.   
  54. void MemoryPool::Free(void* pfree)  
  55. {  
  56.     if(m_pFirst==NULL)  
  57.         return;  
  58.     MemoryBlock* pmb_block=m_pFirst;  
  59.     MemoryBlock* pmb_preblock=m_pFirst;  
  60.     while((ULONG)pfree<(ULONG)pmb_block->m_data||  
  61.         (ULONG)pfree>(ULONG)(pmb_block->m_data+pmb_block->m_nSize))//pfree不在当前block中  
  62.     {  
  63.         pmb_preblock=pmb_block;//前一个block块  
  64.         pmb_block=pmb_block->m_pNext;  
  65.         if(!pmb_block)  
  66.             return;  
  67.     }  
  68.     pmb_block->m_nFree++;//可分配数目+1  
  69.     *((USHORT*)pfree)=pmb_block->m_nFirst;  
  70.     pmb_block->m_nFirst=(USHORT)((ULONG)pfree-(ULONG)pmb_block->m_data)/m_nUnitSize;  
  71.     if(pmb_block->m_nFree*m_nUnitSize==pmb_block->m_nSize)//如何该链块为空  
  72.     {  
  73.         pmb_preblock->m_pNext=pmb_block->m_pNext;  
  74.         if((ULONG)pmb_preblock==(ULONG)m_pFirst)  
  75.             m_pFirst=NULL;  
  76.         delete pmb_block;  
  77.     }  
  78. }  
  79.   
  80. MemoryPool::~MemoryPool(void)  
  81. {  
  82.     if(m_pFirst)  
  83.         FreeMemoryBlock(m_pFirst);  
  84. }  
  85.   
  86. void MemoryPool::FreeMemoryBlock(MemoryBlock *pblock)  
  87. {  
  88.     if(pblock->m_pNext)  
  89.         FreeMemoryBlock(pblock->m_pNext);  
  90.     delete pblock;  
  91.     pblock=NULL;  
  92. }  
  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值