內存塊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;
- }