您的位置:首页 > 编程语言 > C语言/C++

内存池的C++实现。

2014-09-26 16:53 246 查看
原文:http://blog.csdn.net/gisfarmer/article/details/4099499

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

内存块MemoryBlock声明文件

[cpp] view
plaincopy

#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声明文件

[cpp] view
plaincopy

#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实现文件

[cpp] view
plaincopy

#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: