内存池的C++实现
由于毕业设计需要使用到内存池,用以提高程序性能,上网查阅资料,在《C++应用程序性能优化》一书中,提到了内存池的实现(http://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html?ca=drs-cn ,可以在线浏览内存池相关章节)
下面是实现的代码:
MemoryBlock.h
MemoryBlock.cpp
MemoryPool.h
#include "MemoryBlock.h"
#define MEMPOOL_ALIGNMENT 4

class CMemoryPool
{
public:
CMemoryPool(USHORT uUnitSize,USHORT uInitSize,USHORT uGrowSize);
virtual ~CMemoryPool();
void* Alloc();
void Free(void* pFree);
private:
void FreeMemeoryBlock(CMemoryBlock* pMyBlock);
CMemoryBlock* pBlock; //第一个block的指针
USHORT nUnitSize; //每个小内存块的字节数
USHORT nInitSize; //初始的Block的内存块数目
USHORT nGrowSize; //增加的Block的内存块数目
};
MemoryPool.cpp
下面是实现的代码:
MemoryBlock.h
1
class CMemoryBlock
2
{
3
public:
4
CMemoryBlock (USHORT nTypes = 1, USHORT nUnitSize = 0);
5
virtual ~CMemoryBlock();
6
7
void operator delete(void *p,size_t);
8
void * operator new(size_t,USHORT nTypes, USHORT nUnitSize);
9
10
public:
11
USHORT nSize; //内存块的大小 每个小块所占内存*小块个数
12
USHORT nFree; //空闲块数
13
USHORT nFirst; //第一个空闲块
14
//USHORT nDummyAlign1;
15
CMemoryBlock* pNext; //下一个Block
16
char aData[1]; //数据的初始位置
17
18
};
class CMemoryBlock 2
{3
public:4
CMemoryBlock (USHORT nTypes = 1, USHORT nUnitSize = 0); 5
virtual ~CMemoryBlock();6
7
void operator delete(void *p,size_t);8
void * operator new(size_t,USHORT nTypes, USHORT nUnitSize); 9
10
public:11
USHORT nSize; //内存块的大小 每个小块所占内存*小块个数12
USHORT nFree; //空闲块数13
USHORT nFirst; //第一个空闲块14
//USHORT nDummyAlign1; 15
CMemoryBlock* pNext; //下一个Block16
char aData[1]; //数据的初始位置17

18
};MemoryBlock.cpp
1
#include "MemoryBlock.h"
2
3
#ifdef _DEBUG
4
//#define new DEBUG_NEW
5
#undef THIS_FILE
6
static char THIS_FILE[]=__FILE__;
7
#endif
8
9
//////////////////////////////////////////////////////////////////////
10
// Construction/Destruction
11
//////////////////////////////////////////////////////////////////////
12
13
14
CMemoryBlock::~CMemoryBlock()
15
{
16
17
}
18
19
void * CMemoryBlock::operator new(size_t,USHORT nTypes, USHORT nUnitSize)
20
{
21
return malloc(sizeof(CMemoryBlock) + nTypes * nUnitSize);
22
}
23
24
void CMemoryBlock::operator delete(void *p,size_t)
25
{
26
::operator delete (p);
27
}
28
29
//初始化
30
CMemoryBlock::CMemoryBlock (USHORT nTypes , USHORT nUnitSize)
31
{
32
nFree = nTypes - 1;
33
pNext = NULL;
34
nSize = nTypes * nUnitSize;
35
nFirst = 1;
36
37
char* pData=aData;
38
for(USHORT i=1;i<nTypes;i++)
39
{
40
*(USHORT*)pData=i;
41
pData+=nUnitSize;
42
}
43
}
#include "MemoryBlock.h"2

3
#ifdef _DEBUG4
//#define new DEBUG_NEW5
#undef THIS_FILE6
static char THIS_FILE[]=__FILE__;7
#endif8

9
//////////////////////////////////////////////////////////////////////10
// Construction/Destruction11
//////////////////////////////////////////////////////////////////////12

13

14
CMemoryBlock::~CMemoryBlock()15
{16

17
}18

19
void * CMemoryBlock::operator new(size_t,USHORT nTypes, USHORT nUnitSize)20
{21
return malloc(sizeof(CMemoryBlock) + nTypes * nUnitSize);22
}23

24
void CMemoryBlock::operator delete(void *p,size_t)25
{26
::operator delete (p);27
}28

29
//初始化30
CMemoryBlock::CMemoryBlock (USHORT nTypes , USHORT nUnitSize)31
{32
nFree = nTypes - 1;33
pNext = NULL;34
nSize = nTypes * nUnitSize;35
nFirst = 1;36

37
char* pData=aData;38
for(USHORT i=1;i<nTypes;i++)39
{40
*(USHORT*)pData=i;41
pData+=nUnitSize;42
}43
}MemoryPool.h
#include "MemoryBlock.h"
#define MEMPOOL_ALIGNMENT 4
class CMemoryPool
{
public:
CMemoryPool(USHORT uUnitSize,USHORT uInitSize,USHORT uGrowSize);
virtual ~CMemoryPool();
void* Alloc();
void Free(void* pFree);
private:
void FreeMemeoryBlock(CMemoryBlock* pMyBlock);
CMemoryBlock* pBlock; //第一个block的指针
USHORT nUnitSize; //每个小内存块的字节数
USHORT nInitSize; //初始的Block的内存块数目
USHORT nGrowSize; //增加的Block的内存块数目
};MemoryPool.cpp
1
#include "MemoryPool.h"
2
3
#ifdef _DEBUG
4
#undef THIS_FILE
5
static char THIS_FILE[]=__FILE__;
6
//#define new DEBUG_NEW
7
#endif
8
9
//////////////////////////////////////////////////////////////////////
10
// Construction/Destruction
11
//////////////////////////////////////////////////////////////////////
12
13
CMemoryPool::~CMemoryPool()
14
{
15
CMemoryBlock* pMyBlock = pBlock;
16
if(pBlock)
17
FreeMemeoryBlock(pMyBlock);
18
}
19
20
//递归释放内存
21
void CMemoryPool::FreeMemeoryBlock(CMemoryBlock *pMyBlock)
22
{
23
if(pMyBlock->pNext)
24
FreeMemeoryBlock(pMyBlock->pNext);
25
26
delete pMyBlock;
27
}
28
29
30
CMemoryPool::CMemoryPool(USHORT _uUnitSize,USHORT _uInitSize,USHORT _uGrowSize)
31
{
32
pBlock=NULL;
33
nInitSize=_uInitSize;
34
nGrowSize=_uGrowSize;
35
36
if(_uUnitSize<=2)
37
nUnitSize=2;
38
else if(_uUnitSize>2 && _uUnitSize<=4)
39
nUnitSize=4;
40
else
41
{
42
if(_uUnitSize % MEMPOOL_ALIGNMENT ==0)
43
nUnitSize=_uUnitSize;
44
else
45
nUnitSize=(_uUnitSize/MEMPOOL_ALIGNMENT+1)*MEMPOOL_ALIGNMENT;
46
}
47
}
48
49
//申请内存
50
void* CMemoryPool::Alloc()
51
{
52
if(!pBlock)
53
{
54
pBlock=new(nInitSize,nUnitSize) CMemoryBlock(nInitSize,nUnitSize);
55
return pBlock->aData;
56
}
57
58
CMemoryBlock * pMyBlock=pBlock;
59
while(pMyBlock && !pMyBlock->nFree)
60
pMyBlock = pMyBlock->pNext;
61
62
//接下来的两种情况:1.找到有空闲块的block 2.找不到
63
void * retval;
64
if(pMyBlock)
65
{
66
pMyBlock->nFree--;
67
retval = pMyBlock->aData + nUnitSize * pMyBlock->nFirst;
68
pMyBlock->nFirst = *((USHORT*)retval);
69
return retval;
70
}
71
else
72
{
73
if(!nGrowSize)
74
return NULL;
75
CMemoryBlock* newBlock = new(nGrowSize,nUnitSize) CMemoryBlock(nGrowSize,nUnitSize);
76
if(!newBlock)
77
return NULL;
78
newBlock->pNext = pBlock;
79
pBlock = newBlock;
80
return (void*)(newBlock->aData);
81
}
82
83
return NULL;
84
}
85
86
void CMemoryPool::Free(void* pFree)
87
{
88
CMemoryBlock* pMyBlock = pBlock;
89
CMemoryBlock* pPreBlock = NULL; //pMyBlock指向Block的前一个Block,用于设置pNext
90
while((ULONG)pFree < (ULONG)pMyBlock->aData || (ULONG)pFree > (ULONG)(pMyBlock->aData + pMyBlock->nSize))
91
{
92
pPreBlock = pMyBlock;
93
pMyBlock = pMyBlock->pNext;
94
95
if(!pMyBlock)
96
return;
97
}
98
if(pMyBlock)
99
{
100
pMyBlock->nFree++;
101
*((USHORT*)pFree) = pMyBlock->nFirst;
102
pMyBlock->nFirst = (USHORT)(((ULONG)pFree - (ULONG)pMyBlock->aData)/nUnitSize);
103
104
if(pMyBlock->nFree * nUnitSize == pMyBlock->nSize) //如果全是自由块
105
{
106
if(!pMyBlock->pNext) //如果这是最后一个block,则将其释放
107
{
108
delete pMyBlock; //释放
109
if(pPreBlock)
110
pPreBlock->pNext = NULL; //设置上一块的pNext指向NULL
111
else
112
pBlock = NULL;
113
}
114
115
}
116
}
117
}
#include "MemoryPool.h"2

3
#ifdef _DEBUG4
#undef THIS_FILE5
static char THIS_FILE[]=__FILE__;6
//#define new DEBUG_NEW7
#endif8

9
//////////////////////////////////////////////////////////////////////10
// Construction/Destruction11
//////////////////////////////////////////////////////////////////////12

13
CMemoryPool::~CMemoryPool()14
{15
CMemoryBlock* pMyBlock = pBlock;16
if(pBlock)17
FreeMemeoryBlock(pMyBlock);18
}19

20
//递归释放内存21
void CMemoryPool::FreeMemeoryBlock(CMemoryBlock *pMyBlock)22
{23
if(pMyBlock->pNext)24
FreeMemeoryBlock(pMyBlock->pNext);25

26
delete pMyBlock;27
}28

29

30
CMemoryPool::CMemoryPool(USHORT _uUnitSize,USHORT _uInitSize,USHORT _uGrowSize)31
{32
pBlock=NULL;33
nInitSize=_uInitSize;34
nGrowSize=_uGrowSize;35
36
if(_uUnitSize<=2)37
nUnitSize=2;38
else if(_uUnitSize>2 && _uUnitSize<=4)39
nUnitSize=4;40
else 41
{42
if(_uUnitSize % MEMPOOL_ALIGNMENT ==0)43
nUnitSize=_uUnitSize;44
else45
nUnitSize=(_uUnitSize/MEMPOOL_ALIGNMENT+1)*MEMPOOL_ALIGNMENT;46
}47
}48

49
//申请内存50
void* CMemoryPool::Alloc()51
{52
if(!pBlock)53
{54
pBlock=new(nInitSize,nUnitSize) CMemoryBlock(nInitSize,nUnitSize);55
return pBlock->aData;56
}57

58
CMemoryBlock * pMyBlock=pBlock;59
while(pMyBlock && !pMyBlock->nFree)60
pMyBlock = pMyBlock->pNext;61

62
//接下来的两种情况:1.找到有空闲块的block 2.找不到63
void * retval;64
if(pMyBlock)65
{66
pMyBlock->nFree--;67
retval = pMyBlock->aData + nUnitSize * pMyBlock->nFirst;68
pMyBlock->nFirst = *((USHORT*)retval);69
return retval;70
}71
else72
{73
if(!nGrowSize)74
return NULL;75
CMemoryBlock* newBlock = new(nGrowSize,nUnitSize) CMemoryBlock(nGrowSize,nUnitSize);76
if(!newBlock)77
return NULL;78
newBlock->pNext = pBlock;79
pBlock = newBlock;80
return (void*)(newBlock->aData);81
}82
83
return NULL;84
}85

86
void CMemoryPool::Free(void* pFree)87
{88
CMemoryBlock* pMyBlock = pBlock;89
CMemoryBlock* pPreBlock = NULL; //pMyBlock指向Block的前一个Block,用于设置pNext90
while((ULONG)pFree < (ULONG)pMyBlock->aData || (ULONG)pFree > (ULONG)(pMyBlock->aData + pMyBlock->nSize))91
{92
pPreBlock = pMyBlock;93
pMyBlock = pMyBlock->pNext;94

95
if(!pMyBlock)96
return;97
}98
if(pMyBlock)99
{100
pMyBlock->nFree++;101
*((USHORT*)pFree) = pMyBlock->nFirst;102
pMyBlock->nFirst = (USHORT)(((ULONG)pFree - (ULONG)pMyBlock->aData)/nUnitSize);103
104
if(pMyBlock->nFree * nUnitSize == pMyBlock->nSize) //如果全是自由块105
{106
if(!pMyBlock->pNext) //如果这是最后一个block,则将其释放107
{108
delete pMyBlock; //释放109
if(pPreBlock)110
pPreBlock->pNext = NULL; //设置上一块的pNext指向NULL111
else112
pBlock = NULL;113
}114
115
}116
}117
}



浙公网安备 33010602011771号