最近在学习c++程序性能优化,读到内存池部分。自己动手写了一个,小小测试了一下应该没有问题。 内存块MemoryBlock声明文件 #pragma once #define USHORT unsigned short #define ULONG unsigned long #include <iostream> using namespace std; //内存块 struct MemoryBlock { USHORT m_nSize;//可分配内存总大小 USHORT m_nFree;//可分配内存单元数目 USHORT m_nFirst;//第一个可用的内存单元位置 MemoryBlock* m_pNext;//指向下一个内存块 char m_data[1]; void* operator new(size_t,const USHORT& sum,const USHORT& unit_size) { return ::operator new(sizeof(MemoryBlock)+sum*unit_size);//申请一个内存块空间 } void operator delete(void* del,size_t) { ::operator delete(del);//删除内存块空间 } MemoryBlock(const USHORT& sum,const USHORT& unit_size) :m_nSize(sum*unit_size),m_nFree(sum-1),m_nFirst(1),m_pNext(0) { char* pData=m_data; for(int i=1;i<sum;i++)//初始化1到sum-1指向 { *reinterpret_cast<USHORT*>(pData)=i; pData+=unit_size; } } ~MemoryBlock(){} }; 内存池MemoryPool声明文件 #pragma once #include "MemoryBlock.h" //内存池 a very good memory manager class MemoryPool { private: USHORT m_nUnitSize;//一个可分配单元的大小 USHORT m_nInitSize;//第一个可分配空间数目 USHORT m_nGrowSize;//新增的可分配空间数目 MemoryBlock* m_pFirst;//指向第一个内存块 public: //单元大小,第一个内存块的可分配空间数目,第二个内存块之后的可分配空间数目 MemoryPool(const USHORT& unit_size,const USHORT& init_size=2048,const USHORT& grow_size=1024); ~MemoryPool(void); void* Alloc();//分配内存 void Free(void* pfree);//回收内存 void FreeMemoryBlock(MemoryBlock *pblock);//销毁 }; 内存池MemoryPool实现文件 #include "MemoryPool.h" const USHORT MEMPOOL_ALIGNMENT=2; MemoryPool::MemoryPool(const USHORT &unit_size, const USHORT &init_size, const USHORT &grow_size) :m_pFirst(0), m_nInitSize(init_size), m_nGrowSize(grow_size) { if(unit_size>4) { m_nUnitSize = (unit_size + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1); //m_nUnitSize 取整到大于unit_size的最大的MEMPOOL_ALIGNMENT的倍数. //令人纠结的注释 } else if(unit_size>=2) m_nUnitSize=4; else m_nUnitSize=2; } void* MemoryPool::Alloc() { if(!m_pFirst)//如果是第一次申请 { MemoryBlock* pmb_first=new (m_nInitSize,m_nUnitSize)MemoryBlock(m_nInitSize,m_nUnitSize);//14日凌晨至此 m_pFirst=pmb_first; return (void*)pmb_first->m_data; } MemoryBlock* pmb_block=m_pFirst; while(pmb_block&&pmb_block->m_nFree==0)//pmb_block没走到最后并且当前block没有可分配结点 { pmb_block=pmb_block->m_pNext;//往后走吧。 } if(pmb_block)//如果找到可分配结点的block { char* pfree=pmb_block->m_data+(pmb_block->m_nFirst*m_nUnitSize); pmb_block->m_nFirst=*((USHORT*)pfree); pmb_block->m_nFree--;//可分配节点自减 return (void*)pfree; } else//如果找不到,此时pmb_block值为0 { if(m_nGrowSize==NULL) return NULL; pmb_block=new (m_nGrowSize,m_nUnitSize)MemoryBlock(m_nGrowSize,m_nUnitSize); if(!pmb_block)//new不成功 return NULL; pmb_block->m_pNext=m_pFirst;//把新建的block放到最前吧 m_pFirst=pmb_block; return (void*)pmb_block->m_data; } } void MemoryPool::Free(void* pfree) { if(m_pFirst==NULL) return; MemoryBlock* pmb_block=m_pFirst; MemoryBlock* pmb_preblock=m_pFirst; while((ULONG)pfree<(ULONG)pmb_block->m_data|| (ULONG)pfree>(ULONG)(pmb_block->m_data+pmb_block->m_nSize))//pfree不在当前block中 { pmb_preblock=pmb_block;//前一个block块 pmb_block=pmb_block->m_pNext; if(!pmb_block) return; } pmb_block->m_nFree++;//可分配数目+1 *((USHORT*)pfree)=pmb_block->m_nFirst; pmb_block->m_nFirst=(USHORT)((ULONG)pfree-(ULONG)pmb_block->m_data)/m_nUnitSize; if(pmb_block->m_nFree*m_nUnitSize==pmb_block->m_nSize)//如何该链块为空 { pmb_preblock->m_pNext=pmb_block->m_pNext; if((ULONG)pmb_preblock==(ULONG)m_pFirst) m_pFirst=NULL; delete pmb_block; } } MemoryPool::~MemoryPool(void) { if(m_pFirst) FreeMemoryBlock(m_pFirst); } void MemoryPool::FreeMemoryBlock(MemoryBlock *pblock) { if(pblock->m_pNext) FreeMemoryBlock(pblock->m_pNext); delete pblock; pblock=NULL; }