释放双眼,带上耳机,听听看~!
人家对内存块的管理是用vector,动态的插入与删除,来做内存的分配与回收,基于人家的代码,做的一些改动,用Map进行管理,用标志来区分该内存块是否已分配,回收时,内存里面的内容也得重置掉,以免影响下一次的调用。
代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 1
2#ifndef _MEM_POOL_H
3#define _MEM_POOL_H
4
5#include <vector>
6#include <iostream>
7#include <map>
8#include "string.h"
9
10
11using namespace std;
12
13/*
14在内存池中分配固定大小的内存块
15
16该类的目的是加速内存分配速度,并且减少因重复分配相同
17内存时产生的内存碎片,比如在服务器应用程序中。
18*/
19
20struct sBlock
21{
22 short isHasUse; // 是否使用过
23 int iIndx; // 编号
24 char* pBlock; // 内存块所指向的地址
25};
26
27class CMemPool
28{
29public:
30
31 //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc
32 CMemPool(std::size_t blockSize, int preAlloc = 0);
33
34 ~CMemPool();
35
36 //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块
37 //如果分配的内存块数目达到了最大值,则会返回一个异常
38 void* Get();
39
40 //释放当前内存块,将其插入内存池
41 void Release(void* ptr);
42
43 //返回内存块大小
44 std::size_t BlockSize() const;
45
46 //返回内存池中内存块数目
47 int Allocated() const;
48
49 //返回内存池中可用的内存块数目
50 int Available() const;
51
52 //得到内存块的数量
53 int GetBlockNum() const;
54
55private:
56 CMemPool();
57 CMemPool(const CMemPool&);
58 CMemPool& operator = (const CMemPool&);
59
60 enum
61 {
62 BLOCK_RESERVE = 32
63 };
64
65 typedef std::vector<char*> BlockVec;
66
67 std::size_t m_blockSize;
68 int m_maxAlloc;
69 int m_allocated;
70 BlockVec m_blocks;
71
72 typedef map<int, sBlock> BlockMap;
73 BlockMap m_blocks_map;
74
75};
76
77inline std::size_t CMemPool::BlockSize() const
78{
79 return m_blockSize;
80}
81
82
83// 得到已经分配出去的有多少
84inline int CMemPool::Allocated() const
85{
86 int iTotalUseNum = 0;
87 for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
88 {
89 if (it->second.isHasUse == 1)
90 {
91 iTotalUseNum += 1;
92 }
93 }
94 return iTotalUseNum;
95}
96
97inline int CMemPool::Available() const
98{
99 int iAvailableNum = 0;
100 for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
101 {
102 if (it->second.isHasUse == 0)
103 {
104 iAvailableNum += 1;
105 }
106 }
107 return iAvailableNum;
108}
109
110inline int CMemPool::GetBlockNum() const
111{
112 return m_blocks_map.size();
113}
114
115CMemPool::CMemPool(std::size_t blockSize, int preAlloc) :
116m_blockSize(blockSize),
117m_allocated(preAlloc)
118{
119 m_blocks_map.clear();
120 for (int i = 0; i < preAlloc; ++i)
121 {
122 sBlock nBlock;
123 nBlock.isHasUse = 0;
124 nBlock.iIndx = i;
125 nBlock.pBlock = new char[m_blockSize];
126 m_blocks_map[i] = nBlock;
127 }
128
129}
130
131CMemPool::~CMemPool()
132{
133 for (BlockMap::iterator it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
134 {
135
136 cout << " delete the block indx = " << it->second.iIndx << " " << endl;
137 delete[] it->second.pBlock; // 删除内存对应的内存空间
138 }
139 m_blocks_map.clear();
140}
141
142
143void* CMemPool::Get()
144{
145 // 分配内存地址
146 for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
147 {
148 if (it->second.isHasUse == 0)
149 {
150 it->second.isHasUse = 1; // 表示该内存块已经被分配出去了
151 cout << " this block indx = " << it->second.iIndx << " has be used " << endl;
152 return it->second.pBlock;
153 }
154 }
155
156 // 如果内存map 都被用完啦,那么则得添加新的内存块到map中
157 auto iter = m_blocks_map.end();
158 iter--; // 得往后减一个,才能取到最后一个元素
159
160 int maxIndx = iter->second.iIndx;
161
162 int curIndx = maxIndx + 1;
163 sBlock nBlock;
164 nBlock.iIndx = curIndx;
165 nBlock.isHasUse = 0;
166 nBlock.pBlock = new char[m_blockSize];
167 m_blocks_map[curIndx] = nBlock;
168
169 // 将新添加的分配出来用
170 m_blocks_map[curIndx].isHasUse = 1;
171 cout << " this block indx = " << m_blocks_map[curIndx].iIndx << " create and has be used " << endl;
172 return m_blocks_map[curIndx].pBlock;
173
174}
175
176
177void CMemPool::Release(void* ptr)
178{
179 for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
180 {
181 char * pTmp = reinterpret_cast<char*>(ptr);
182 if (it->second.pBlock == pTmp)
183 {
184 cout << " the block indx = " << it->second.iIndx << " has be Released " << endl;
185 it->second.isHasUse = 0;
186 memset(pTmp, 0, m_blockSize);
187 }
188 }
189}
190
191
192#endif
193
测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 1#include "MemPool.h"
2
3#define DATA_BLOCK_LEN 50
4
5struct sTest
6{
7 int m_id;
8 int m_num;
9};
10
11struct sTest2
12{
13 int m_id;
14 int m_num;
15 char m_str[10];
16};
17
18int main()
19{
20 CMemPool myPool1(DATA_BLOCK_LEN, 20);
21
22 cout << "myPool1 block size = " << myPool1.BlockSize() << endl;
23 cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
24 cout << "myPool1 available block num = " << myPool1.Available() << endl;
25 cout << "myPool1 total block num = " << myPool1.GetBlockNum() << endl <<endl;
26
27 // 分配一个内存块
28 struct sTest* pTest;
29 pTest = (struct sTest*)(myPool1.Get());
30
31 pTest->m_id = 25;
32 pTest->m_num = 10000;
33 cout << pTest->m_id <<" " <<pTest->m_num << endl;
34
35 struct sTest* pTest2;
36 pTest2 = (struct sTest*)(myPool1.Get());
37
38 pTest2->m_id = 123;
39 pTest2->m_num = 13445;
40 cout << pTest2->m_id << " " << pTest2->m_num << endl << endl;
41
42
43 cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
44 cout << "myPool1 available block num = " << myPool1.Available() << endl << endl;
45
46 // 回收该内存块
47 myPool1.Release(pTest);
48 pTest = NULL;
49
50 cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
51 cout << "myPool1 available block num = " << myPool1.Available() << endl << endl;
52
53 //pTest = (struct sTest*)(myPool1.Get());
54 //cout << pTest->m_id << endl;
55 //cout << pTest->m_num << endl;
56 struct sTest2* pTtmp;
57 pTtmp = (struct sTest2*)(myPool1.Get());
58 pTtmp->m_id = 1234;
59 char * cTmp= "skskdlsl";
60 memcpy(pTtmp->m_str, cTmp, strlen(cTmp));
61 cout << pTtmp->m_str << endl;
62
63 cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
64 cout << "myPool1 available block num = " << myPool1.Available() << endl << endl;
65
66 myPool1.Release(pTtmp);
67
68 for (int i = 0; i < 30; ++i)
69 {
70 struct sTest* pTest3;
71 pTest3 = (struct sTest*)(myPool1.Get());
72
73 pTest3->m_id = 123;
74 pTest3->m_num = 13445;
75 cout << pTest3->m_id << " " << pTest3->m_num << endl << endl;
76 cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
77 cout << "myPool1 available block num = " << myPool1.Available() << endl;
78 cout << "myPool1 total block num = " << myPool1.GetBlockNum() << endl << endl;
79 }
80
81 int iWait;
82 cin >> iWait;
83
84 return 0;
85}
86