内存池


MemoryBlock.h

#ifndef MEMORY_BLOCK
#define MEMORY_BLOCK
typedef unsigned short USHORT;
/
#include <iostream>
#include <new>
using namespace std;

class  MemoryBlock
{
	public:
		MemoryBlock(USHORT nTypes = 1, USHORT nUnitSize = 0); //nType:一个大块包含的内存单元个数。nUnitSize:内存单元字节数
		~MemoryBlock();

		static void* operator new(size_t, USHORT nTypes, USHORT nUnitSize);
		static void operator delete(void *p, size_t);//出现warning C4291
		static void my_new_handler();

		USHORT nSize;
		USHORT nFree;
		USHORT nFirst;
		USHORT nDummyAlign1;
		MemoryBlock* pNext;
		char aData[1];

};
/
#endif



MemoryBlock.cpp

#include "MemoryBlock.h"
/
///
MemoryBlock::MemoryBlock(USHORT nTypes, USHORT nUnitSize)
	 : nSize(nTypes * nUnitSize), nFree(nTypes - 1), nFirst(1), pNext(NULL)
{
	char *pData = aData;
	for (USHORT i = 1; i < nTypes; i++)
	{
		*(USHORT*)(pData) = i;
		pData += nUnitSize;
	}
	nSize = nTypes * nUnitSize;
}
/
void MemoryBlock::my_new_handler()
{
	cout << "内存池内存申请失败" << endl;
	throw bad_alloc();
}
/
MemoryBlock::~MemoryBlock(){}

/
void* MemoryBlock::operator new(size_t, USHORT nTypes, USHORT nUnitSize)
{
	new_handler global_handler = set_new_handler(my_new_handler);//设置内存申请异常处理函数
	return ::operator new(sizeof(MemoryBlock) + nTypes * nUnitSize);//向系统申请内存
	set_new_handler(global_handler);
}

/
void MemoryBlock::operator delete(void *p, size_t)
{
	::operator delete (p);
}



MemoryBlock.cpp


#include "MemoryBlock.h"
/
///
MemoryBlock::MemoryBlock(USHORT nTypes, USHORT nUnitSize)
	 : nSize(nTypes * nUnitSize), nFree(nTypes - 1), nFirst(1), pNext(NULL)
{
	char *pData = aData;
	for (USHORT i = 1; i < nTypes; i++)
	{
		*(USHORT*)(pData) = i;
		pData += nUnitSize;
	}
	nSize = nTypes * nUnitSize;
}
/
void MemoryBlock::my_new_handler()
{
	cout << "内存池内存申请失败" << endl;
	throw bad_alloc();
}
/
MemoryBlock::~MemoryBlock(){}

/
void* MemoryBlock::operator new(size_t, USHORT nTypes, USHORT nUnitSize)
{
	new_handler global_handler = set_new_handler(my_new_handler);//设置内存申请异常处理函数
	return ::operator new(sizeof(MemoryBlock) + nTypes * nUnitSize);//向系统申请内存
	set_new_handler(global_handler);
}

/
void MemoryBlock::operator delete(void *p, size_t)
{
	::operator delete (p);
}



MemoryPool.h


#ifndef MEMORY_POOL
#define MEMORY_POOL
typedef unsigned short USHORT;
typedef unsigned long ULONG;

///
#include"MemoryBlock.h"

class MemoryPool
{
	public:
		//nUnitSize:内存单元大小,nInitSize:第一个内存块包含的内存单元个数,nGrowSize:非第一个内存块包含的内存单元个数
		MemoryPool(USHORT nUnitSize, USHORT nInitSize = 1024, USHORT nGrowSize = 256);
		~MemoryPool();
		void* Alloc();
		void Free(void* p);
	private:
		MemoryBlock*	pBlock;
		USHORT			nUnitSize;
		USHORT			nInitSize;
		USHORT			nGrowSize;
};

///
#endif

MemoryPool.cpp


#include "MemoryPool.h"
const USHORT MEMPOOL_ALIGNMENT=2;
///
MemoryPool::MemoryPool(USHORT _nUnitSize, USHORT _nInitSize, USHORT _nGrowSize) 
	: pBlock(NULL), nInitSize(_nInitSize), nGrowSize(_nGrowSize)
{
	if (_nUnitSize > 4)
	{
		nUnitSize = (_nUnitSize + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);
	}
	else if (_nUnitSize <= 2)
	{
		nUnitSize = 2;
	}
	else
	{
		nUnitSize = 4;
	}
	
}

///
void* MemoryPool::Alloc()
{
	//第一次使用内存池
	if (!pBlock)
	{ 
		pBlock = new(nInitSize, nUnitSize) MemoryBlock(nInitSize, nUnitSize);
		return (void*)(pBlock->aData);
	}

	MemoryBlock* pMyBlock = pBlock;
	//寻找一个有空闲内存单元的块
	while (pMyBlock && !pMyBlock->nFree)
		pMyBlock = pMyBlock->pNext;
	//如果找到了有空闲内存单元的块,分配内存单元
	if(pMyBlock != NULL)
	{
		char* pFree = pMyBlock->aData + (pMyBlock->nFirst * nUnitSize);
		pMyBlock->nFirst = *((USHORT*)pFree);
		(pMyBlock->nFree)--;
		return (void*)pFree;
	}
	//内存池中的内存单元用光了,再向系统申请一大块内存
	else
	{
		if (!nGrowSize)
		{
			return NULL;
		}
		pMyBlock = new(nGrowSize, nUnitSize) MemoryBlock (nGrowSize, nUnitSize);
		if (!pMyBlock)
		{
			return NULL;
		}
		//把大块内存加入到内存池的前面
		pMyBlock->pNext = pBlock;
		pBlock = pMyBlock;
		return (void*)(pMyBlock->aData);
	}
}



///
void MemoryPool::Free(void* pFree)
{
	MemoryBlock* pMyBlock = pBlock;
	MemoryBlock* preBlock = pBlock;
	//确定pFree在哪个块中
	while ( ((ULONG)pMyBlock->aData > (ULONG)pFree) || ((ULONG)pFree >= ((ULONG)pMyBlock->aData + pMyBlock->nSize)) )
	{
		preBlock = pMyBlock;
		pMyBlock = pMyBlock->pNext;
		if (pMyBlock == NULL)
		{
			return;
		}
	}
	(pMyBlock->nFree)++;
	//把刚刚回收的内存单元放在最前面
	*((USHORT*)pFree) = pMyBlock->nFirst;
	pMyBlock->nFirst = (USHORT)(((ULONG)pFree - (ULONG)(pBlock->aData)) / nUnitSize);//确定回收的内存单元的编号

	//判断是否需要把整个内存块返还给系统
	if (pMyBlock->nFree*nUnitSize == pMyBlock->nSize)
	{
		//是否是第一个内存块
		if (preBlock == pMyBlock)
		{
			pBlock = pMyBlock->pNext;
		}
		else
		{
			preBlock->pNext = pMyBlock->pNext;
		}
			delete pMyBlock;
	}
}
///
MemoryPool::~MemoryPool()
{
	MemoryBlock* NextBlock = pBlock;
	while (pBlock)
	{
		NextBlock = pBlock->pNext;
		delete pBlock;
		pBlock = NextBlock;
	}
}

hight_time.h

#include <windows.h>

class High_Timer
{
	private:
		_LARGE_INTEGER TimeStart;
		_LARGE_INTEGER TimeEnd;
	public:
		void Start();//计时开始
		void End();//计时结束 
		double Timer();//返回时差
};


#endif

hight_time.cpp

#include "High_Time.h"
///
///
void High_Timer::Start()
{
    QueryPerformanceCounter(&TimeStart);    //计时开始
}

void High_Timer::End()
{
    QueryPerformanceCounter(&TimeEnd);    //计时结束
}
///
double High_Timer::Timer()
{
    static double Freq;//计时器频率
    static bool getfreq = false;
    if (!getfreq)//获得计时器频率,只运行一次
    {
        LARGE_INTEGER f;
        if (QueryPerformanceFrequency(&f))
            Freq = f.QuadPart;
        else
            throw "无法获得定时器频率";
        getfreq = true;
    }
    return (TimeEnd.QuadPart - TimeStart.QuadPart) / Freq;
}

test


#include "MemoryPool.h"
#include "High_Time.h"

int	main()
{
	int* p[3000];
	int i;
	High_Timer time_Test;

	time_Test.Start();
	for (i = 0; i != 3000; i++)
	{
		p[i] = new int;
	}
	for (i = 0; i != 3000; i++)
	{
		delete p[i];
	}
	time_Test.End();
	cout << "no using MemoryPool:" << time_Test.Timer() << endl;

	time_Test.Start();
	MemoryPool Mp_test(sizeof(int), 1024, 512);
	for (i = 0; i != 3000; i++)
	{
		p[i] = (int*)Mp_test.Alloc();
	}
	for (i = 0; i != 3000; i++)
	{
		Mp_test.Free(p[i]);
	}
	time_Test.End();
	cout << "using MemoryPool:" << time_Test.Timer() << endl;

	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值