内存池

#include<iostream>
#include<vector>

using namespace std;

#define USHORT int
#define ULONG  long
#define MEMPOOL_ALIGNMENT 4

struct CMemBlock
{
public:
int nSize;
int nfree;
USHORT nfirst;
CMemBlock* pnext;
char aData[1];

CMemBlock(USHORT m_InitSize, USHORT nUnitSize);
~CMemBlock();
static void* operator new(size_t, USHORT m_InitSize, USHORT nUnitSize)
{
return ::operator new(sizeof(CMemBlock) + m_InitSize * nUnitSize);
}

};

CMemBlock::CMemBlock(USHORT m_InitSize, USHORT nUnitSize)
    :nSize(m_InitSize * nUnitSize),
     nfree(m_InitSize-1),
     nfirst(1),
     pnext(0)
{

char * pData = aData;
for (USHORT i = 1; i < m_InitSize; i++)
{
*reinterpret_cast<USHORT*>(pData) = i;
pData += nUnitSize;
}

}

//memorypool
class CMemPool
{
private:
int m_UnitSize;
int m_InitSize;
CMemBlock* pBlock;
public:
CMemPool();
~CMemPool(){}
void* get();
void free(void *p);
void setUnitSize(int UnitSize){m_UnitSize = UnitSize;}
int  getUnitSize(){return m_UnitSize;}
void setInitSize(int InitSize){m_InitSize = InitSize;}
int  getInitSize(){return m_InitSize;}
};
CMemPool::CMemPool()
{
m_UnitSize = 4;
m_InitSize = 100;
pBlock = NULL;

if(m_UnitSize>4)
{
m_UnitSize = (m_UnitSize + MEMPOOL_ALIGNMENT-1)&~(MEMPOOL_ALIGNMENT-1);
}
else if(m_UnitSize<=2)
m_UnitSize = 2;
else
m_UnitSize =4;
}

void* CMemPool::get()
{
if(!pBlock)
{

pBlock = new (m_InitSize,m_UnitSize) CMemBlock(m_InitSize,m_UnitSize);
cout<<"chuangjian chenggong~~~~~~~"<<endl;
return (void *)pBlock->aData;
}
CMemBlock* p1 = pBlock;
while(p1&&!p1->nfree)
p1 = p1->pnext;
if(p1)
{
char* pfree = p1->aData+(p1->nfirst*m_UnitSize);
p1->nfirst = *((USHORT *)pfree);
p1->nfree--;
return (void *)pfree;
}
else
cout<<"~~~~~enough~~~~~~~~";
}
void CMemPool::free(void *p)
{
CMemBlock* p2 = pBlock;
while((((ULONG)p2->aData>(ULONG)p)||(ULONG)p>((ULONG)p2->aData+p2->nSize))&&p2)
{
p2 = p2->pnext;
}

if(p2)
{
p2->nfree++;
*((USHORT*)p) = p2->nfirst;
p2->nfirst = (USHORT)(((ULONG)p-(ULONG)p2->aData)/m_UnitSize);
}
}


int main()
{
    ULONG * p;
CMemPool pool;

int i;
for(i=0;i<101;i++)
{


p=(ULONG *)pool.get();
cout<<*p<<endl;
}
return 0;

}
注:CMemBlock中注意new的用法。n ew delete 操作符我们应该都用过,它们是对堆中的内存进行申请和释放,而这两个都是不能被重载的。要实现不同的内存分配行为,需要重载 operator new ,而不是 new delete

placement new是operator new的一个重载版本,只是我们很少用到它。如果你想在已经分配的内存中创建一个对象,使用new是不行的。也就是说placement new允许你在一个已经分配好的内存中(栈或堆中)构造一个新的对象。原型中void*p实际上就是指向一个已经分配好的内存缓冲区的的首地址。

我们知道使用new操作符分配内存需要在堆中查找足够大的剩余空间,这个操作速度是很慢的,而且有可能出现无法分配内存的异常(空间不够)。placement new就可以解决这个问题。我们构造对象都是在一个预先准备好了的内存缓冲区中进行,不需要查找内存,内存分配的时间是常数;而且不会出现在程序运行中途出现内存不足的异常。所以,placement new非常适合那些对时间要求比较高,长时间运行不希望被打断的应用程序。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值