【链表】关于链表的内存池

  1 //自己写的!
  2 
  3 #include<iostream>
  4 
  5 using namespace std;
  6 
  7 
  8 typedef struct _DATA_
  9 {
 10 
 11     char szName[20];
 12     int iAge;
 13 }Data,*pData;
 14 
 15 typedef struct _NODE_
 16 {
 17     Data DataTemp;
 18     _NODE_* pNext;
 19 }Node,*pNode;
 20 
 21 
 22 class CList
 23 {
 24 public:
 25     CList()
 26     {
 27         m_pHead = m_pTail = NULL;
 28 
 29     }
 30     ~CList()
 31     {
 32 
 33     }
 34 
 35     pNode GetNode(Data DataTemp);
 36     int GetNodeCount();
 37 
 38     //创建一个结点
 39     pNode CreateNode(Data DataTemp, CList& FreeListObj);
 40 
 41     //连接
 42     void LinkNode(pNode pNodeTemp);
 43 
 44     //将结点移回 内存池
 45     void RemoveNode(pNode pNodeTemp,CList& FreeListObj);
 46 
 47     //从内存池链表中提取结点
 48     pNode AllocateNode();
 49 
 50     //回收结点
 51     bool RecycleNode(pNode pNodeTemp);
 52 
 53     bool TravelList();
 54 private:
 55 
 56     pNode m_pHead;
 57     pNode m_pTail;
 58     int m_iNodeCount;
 59 
 60 };
 61 
 62 //创建一个结点,参数为数据的结构体,内存池链表的引用(指针)
 63 pNode CList::CreateNode(Data DataTemp,CList& FreeListObj)
 64 {
 65 
 66     pNode pNodeTemp = NULL;        //申请一个结点的指针
 67 
 68     int iNodeCount = FreeListObj.GetNodeCount();
 69     //判断内存池链表有无内存结点
 70 
 71     //如果内存池当中存在结点,那么直接从内存池中提取出来(直接用)
 72     if(iNodeCount > 0)
 73     {
 74         pNodeTemp = 
 75             FreeListObj.AllocateNode();
 76 
 77         cout<<"FreeList"<<endl;
 78     }
 79 
 80     //如果内存池也是空的,那么申请新的结点
 81     else
 82     {
 83         pNodeTemp = new Node;
 84 
 85         cout<<"New"<<endl;
 86     }
 87 
 88     //如果申请成功或者从内存池提取成功
 89     if(pNodeTemp != NULL)
 90     {
 91         pNodeTemp->DataTemp = DataTemp;
 92 
 93         pNodeTemp->pNext = NULL;
 94 
 95         return pNodeTemp;
 96 
 97     }
 98     //如果不成功
 99     else
100     {
101         return NULL;
102     }    
103 }
104 
105 
106 
107 
108 //结点的连接
109 void CList::LinkNode(pNode pNodeTemp)
110 {
111     //如果头结点是空,说明该结点是第一结点,那么头尾指针如下赋值
112     if(m_pHead == NULL)
113     {
114         m_pHead = m_pTail = pNodeTemp;
115     }
116     else
117     {
118         m_pTail->pNext = pNodeTemp;
119 
120         m_pTail = pNodeTemp;
121     }
122 
123     //结点的数量统计
124     m_iNodeCount++;
125 }
126 
127 
128 //将结点移回 内存池  参数: 结点指针,内存池引用(指针)
129 //链表中移除的同时,将移除的结点送入内存池中
130 void CList::RemoveNode(pNode pNodeTemp,CList& FreeListObj)    
131 {
132     //头结点处理: 头结点下移即可
133     if(pNodeTemp == m_pHead)
134     {
135         m_pHead = m_pHead->pNext;
136     }
137     //尾结点处理: 通过头去找,找到尾结点的前一个结点,
138     //将其设置为尾结点并将pNext设置为空
139     else if(pNodeTemp = m_pTail)
140     {
141         pNode pNodePre = m_pHead;
142         while(pNodePre->pNext != pNodeTemp)
143         {
144             pNodePre = pNodePre->pNext;
145         }
146 
147         pNodePre->pNext = NULL;
148 
149         m_pTail = pNodePre;
150     }
151 
152     //一般情况处理
153     else
154     {
155         pNode pNodePre = m_pHead;
156         while(pNodePre->pNext!=pNodeTemp)
157         {
158             pNodePre = pNodePre->pNext;
159         }
160 
161         pNodePre->pNext = pNodeTemp->pNext;
162     }
163 
164     m_iNodeCount--;
165 
166     if(m_iNodeCount == 0)
167     {
168         m_pTail = NULL;
169     }
170 
171     //回收结点
172     //链表中移除的同时,将移除的结点送入内存池中
173     if(!FreeListObj.RecycleNode(pNodeTemp))
174     {
175         cout<<"Error"<<endl;
176     }
177 
178 }
179 
180 int CList::GetNodeCount()
181 {
182     if(m_pHead==NULL)
183     {
184         return 0;
185     }
186 
187     else
188     {
189         return m_iNodeCount;
190     }
191 }
192 
193 pNode CList::GetNode(Data DataTemp)
194 {
195     pNode pNodeTemp = m_pHead;
196     while(pNodeTemp!=NULL)
197     {
198         if(strcmp(
199             pNodeTemp->DataTemp.szName,
200             DataTemp.szName)==0)
201         {
202             return pNodeTemp;
203         }
204     }
205 
206     return NULL;
207 }
208 
209 //从内存池链表中提取一个结点
210 //前提:内存池中有结点,这个前面会判断,所以这里没问题
211 pNode CList::AllocateNode()
212 {
213     if(m_pHead == m_pTail)
214     {
215 
216         m_pTail = NULL;
217     }
218     pNode pNodeTemp = m_pHead;
219 
220     m_pHead = m_pHead->pNext;
221 
222     pNodeTemp->pNext = NULL;
223 
224 
225     m_iNodeCount--;
226 
227     return pNodeTemp;
228 }
229 
230 //回收结点到内存池
231 //直接插入到内存池,结束战斗
232 bool CList::RecycleNode(pNode pNodeTemp)
233 {
234     if(pNodeTemp!=NULL)
235     {
236         pNodeTemp->pNext = m_pHead;
237 
238         m_pHead = pNodeTemp;
239 
240         m_iNodeCount++;
241 
242         return true;
243     }
244 
245     return false;
246 
247 }
248 
249 
250 
251 bool CList::TravelList()
252 {
253     if(m_pHead == NULL)
254     {
255         return false;
256     }
257 
258     pNode pNodeTemp = m_pHead;
259 
260     while(pNodeTemp!=NULL)
261     {
262         cout<<pNodeTemp->DataTemp.szName<<"  "
263             <<pNodeTemp->DataTemp.iAge<<endl;
264 
265         pNodeTemp = pNodeTemp->pNext;
266     }
267     return true;
268 }
269 
270 
271 int main()
272 {
273 
274     
275     CList CurrentList;
276 
277     CList FreeList;
278 
279     int iNum = 0;
280 
281     Data DataTemp = {0};
282 
283     pNode pNodeTemp = NULL;
284 
285     cout<<"Input Num"<<endl;
286     cin>>iNum;
287 
288     while(iNum)
289     {
290         cout<<"Input Name Age"<<endl;
291 
292         cin>>DataTemp.szName;
293         cin>>DataTemp.iAge;
294 
295         pNodeTemp = CurrentList.CreateNode(DataTemp,FreeList);
296 
297         CurrentList.LinkNode(pNodeTemp);
298 
299         iNum--;
300     }
301     CurrentList.TravelList();
302 
303 
304     bool bOk = true;
305     int iMethod;
306 
307     while(bOk)
308     {
309         cout<<"1.  Insert"<<endl;
310         cout<<"2.  Remove"<<endl;
311         cout<<"30.  Exit"<<endl;
312         
313         cin>>iMethod;
314 
315         switch(iMethod)
316         {
317         case 1:
318             cout<<"Input Name Age"<<endl;
319 
320             cin>>DataTemp.szName;
321             cin>>DataTemp.iAge;
322 
323             pNodeTemp = CurrentList.CreateNode(DataTemp,FreeList);
324             CurrentList.LinkNode(pNodeTemp);
325 
326             CurrentList.TravelList();
327 
328             break;
329         case 2:
330             cout<<"Input DataTemp To Remove"<<endl;
331 
332             cin>>DataTemp.szName;
333             cin>>DataTemp.iAge;
334 
335             pNodeTemp = CurrentList.GetNode(DataTemp);
336 
337             CurrentList.RemoveNode(pNodeTemp,FreeList);
338             CurrentList.TravelList();
339             break;
340 
341         case 30:
342             bOk = false;
343             break;
344         }
345 
346     }
347 
348 
349 
350     return 0;
351 
352 }

上面的代码有BUG

下面是debug之后的代码

  1 #include<iostream>
  2 #include<string.h>
  3 using namespace std;
  4 
  5 
  6 typedef struct _DATA_
  7 {
  8 
  9     char szName[20];
 10     int iAge;
 11 }Data,*pData;
 12 
 13 typedef struct _NODE_
 14 {
 15     Data DataTemp;
 16     _NODE_* pNext;
 17 }Node,*pNode;
 18 
 19 
 20 class CList
 21 {
 22 public:
 23     CList()
 24     {
 25         m_pHead = m_pTail = NULL;
 26 
 27     }
 28     ~CList()
 29     {
 30 
 31     }
 32 
 33     pNode GetNode(Data DataTemp);
 34     int GetNodeCount();
 35 
 36     //创建一个结点
 37     pNode CreateNode(Data DataTemp, CList& FreeListObj);
 38 
 39     //连接
 40     void LinkNode(pNode pNodeTemp);
 41 
 42     //将结点移回 内存池
 43     void RemoveNode(pNode pNodeTemp,CList& FreeListObj);
 44 
 45     //从内存池链表中提取结点
 46     pNode AllocateNode();
 47 
 48     //回收结点
 49     bool RecycleNode(pNode pNodeTemp);
 50 
 51     bool TravelList();
 52 private:
 53 
 54     pNode m_pHead;
 55     pNode m_pTail;
 56     int m_iNodeCount;
 57 
 58 };
 59 
 60 //创建一个结点,参数为数据的结构体,内存池链表的引用(指针)
 61 pNode CList::CreateNode(Data DataTemp,CList& FreeListObj)
 62 {
 63 
 64     pNode pNodeTemp = NULL;        //申请一个结点的指针
 65 
 66     int iNodeCount = FreeListObj.GetNodeCount();
 67     //判断内存池链表有无内存结点
 68 
 69     //如果内存池当中存在结点,那么直接从内存池中提取出来(直接用)
 70     if(iNodeCount > 0)
 71     {
 72         pNodeTemp = 
 73             FreeListObj.AllocateNode();
 74 
 75         cout<<"FreeList"<<endl;
 76     }
 77 
 78     //如果内存池也是空的,那么申请新的结点
 79     else
 80     {
 81         pNodeTemp = new Node;
 82 
 83         cout<<"New"<<endl;
 84     }
 85 
 86     //如果申请成功或者从内存池提取成功
 87     if(pNodeTemp != NULL)
 88     {
 89         pNodeTemp->DataTemp = DataTemp;
 90 
 91         pNodeTemp->pNext = NULL;
 92 
 93         return pNodeTemp;
 94 
 95     }
 96     //如果不成功
 97     else
 98     {
 99         return NULL;
100     }    
101 }
102 
103 
104 
105 
106 //结点的连接
107 void CList::LinkNode(pNode pNodeTemp)
108 {
109     //如果头结点是空,说明该结点是第一结点,那么头尾指针如下赋值
110     if(m_pHead == NULL)
111     {
112         m_pHead = m_pTail = pNodeTemp;
113     }
114     else
115     {
116         m_pTail->pNext = pNodeTemp;
117 
118         m_pTail = pNodeTemp;
119     }
120 
121     //结点的数量统计
122     m_iNodeCount++;
123 }
124 
125 
126 //将结点移回 内存池  参数: 结点指针,内存池引用(指针)
127 //链表中移除的同时,将移除的结点送入内存池中
128 void CList::RemoveNode(pNode pNodeTemp,CList& FreeListObj)    
129 {
130     //头结点处理: 头结点下移即可
131     if(pNodeTemp == m_pHead)
132     {
133         m_pHead = m_pHead->pNext;
134     }
135     //尾结点处理: 通过头去找,找到尾结点的前一个结点,
136     //将其设置为尾结点并将pNext设置为空
137     else if(pNodeTemp == m_pTail)
138     {
139         pNode pNodePre = m_pHead;
140         while(pNodePre->pNext != pNodeTemp)
141         {
142             pNodePre = pNodePre->pNext;
143         }
144 
145         pNodePre->pNext = NULL;
146 
147         m_pTail = pNodePre;
148     }
149 
150     //一般情况处理
151     else
152     {
153         pNode pNodePre = m_pHead;
154         while(pNodePre->pNext!=pNodeTemp)
155         {
156             pNodePre = pNodePre->pNext;
157         }
158 
159         pNodePre->pNext = pNodeTemp->pNext;
160     }
161 
162     m_iNodeCount--;
163 
164     if(m_iNodeCount == 0)
165     {
166         m_pTail = NULL;
167     }
168 
169     //回收结点
170     //链表中移除的同时,将移除的结点送入内存池中
171     if(!FreeListObj.RecycleNode(pNodeTemp))
172     {
173         cout<<"Error"<<endl;
174     }
175 
176 }
177 
178 int CList::GetNodeCount()
179 {
180     if(m_pHead==NULL)
181     {
182         return 0;
183     }
184 
185     else
186     {
187         return m_iNodeCount;
188     }
189 }
190 
191 pNode CList::GetNode(Data DataTemp)
192 {
193     pNode pNodeTemp = m_pHead;
194     while(pNodeTemp!=NULL)
195     {
196         if(strcmp(
197             pNodeTemp->DataTemp.szName,
198             DataTemp.szName)==0)
199         {
200             return pNodeTemp;
201         }
202         pNodeTemp = pNodeTemp->pNext;
203     }
204 
205     return NULL;
206 }
207 
208 //从内存池链表中提取一个结点
209 //前提:内存池中有结点,这个前面会判断,所以这里没问题
210 pNode CList::AllocateNode()
211 {
212     if(m_pHead == m_pTail)
213     {
214 
215         m_pTail = NULL;
216     }
217     pNode pNodeTemp = m_pHead;
218 
219     m_pHead = m_pHead->pNext;
220 
221     pNodeTemp->pNext = NULL;
222 
223 
224     m_iNodeCount--;
225 
226     return pNodeTemp;
227 }
228 
229 //回收结点到内存池
230 //直接插入到内存池,结束战斗
231 bool CList::RecycleNode(pNode pNodeTemp)
232 {
233     if(pNodeTemp!=NULL)
234     {
235         pNodeTemp->pNext = m_pHead;
236 
237         m_pHead = pNodeTemp;
238 
239         m_iNodeCount++;
240 
241         return true;
242     }
243 
244     return false;
245 
246 }
247 
248 
249 
250 bool CList::TravelList()
251 {
252     if(m_pHead == NULL)
253     {
254         return false;
255     }
256 
257     pNode pNodeTemp = m_pHead;
258 
259     while(pNodeTemp!=NULL)
260     {
261         cout<<pNodeTemp->DataTemp.szName<<"  "
262             <<pNodeTemp->DataTemp.iAge<<endl;
263 
264         pNodeTemp = pNodeTemp->pNext;
265     }
266     return true;
267 }
268 
269 
270 int main()
271 {
272 
273     
274     CList CurrentList;
275 
276     CList FreeList;
277 
278     int iNum = 0;
279 
280     Data DataTemp = {0};
281 
282     pNode pNodeTemp = NULL;
283 
284     cout<<"Input Num"<<endl;
285     cin>>iNum;
286 
287     while(iNum)
288     {
289         cout<<"Input Name Age"<<endl;
290 
291         cin>>DataTemp.szName;
292         cin>>DataTemp.iAge;
293 
294         pNodeTemp = CurrentList.CreateNode(DataTemp,FreeList);
295 
296         CurrentList.LinkNode(pNodeTemp);
297 
298         iNum--;
299     }
300     CurrentList.TravelList();
301 
302 
303     bool bOk = true;
304     int iMethod;
305 
306     while(bOk)
307     {
308         cout<<"1.  Insert"<<endl;
309         cout<<"2.  Remove"<<endl;
310         cout<<"30.  Exit"<<endl;
311         
312         cin>>iMethod;
313 
314         switch(iMethod)
315         {
316         case 1:
317             cout<<"Input Name Age"<<endl;
318 
319             cin>>DataTemp.szName;
320             cin>>DataTemp.iAge;
321 
322             pNodeTemp = CurrentList.CreateNode(DataTemp,FreeList);
323             CurrentList.LinkNode(pNodeTemp);
324 
325             CurrentList.TravelList();
326 
327             break;
328         case 2:
329             cout<<"Input DataTemp To Remove"<<endl;
330 
331             cin>>DataTemp.szName;
332             cin>>DataTemp.iAge;
333 
334             pNodeTemp = CurrentList.GetNode(DataTemp);
335 
336             if(pNodeTemp == NULL)
337             {
338                 cout<<"No Data."<<endl;
339             }
340             else
341             {
342                 CurrentList.RemoveNode(pNodeTemp,FreeList);
343             }
344             CurrentList.TravelList();
345             break;
346 
347         case 30:
348             bOk = false;
349             break;
350         }
351 
352     }
353 
354 
355 
356     return 0;
357 
358 }

以下文章留着看

http://blog.csdn.net/nanjunxiao/article/details/8970396

http://blog.csdn.net/networkwx/article/details/6326275

http://www.cnblogs.com/bangerlee/archive/2011/08/31/2161421.html

  1 内存池对于长时间运行的程序特别有用,可以减少内存碎片,提高效率,避免内存益处等众多好处,网上流传的内存池模型有很多种大致分为固定快大小的链表(本文采用的),这种内存池的优点是速度快,碎片少,缺点是灵活性不足,但对于搞定能的服务器端程序而言很多的数据都是已知的,为了追求速度这种牺牲是可以理解的;另外还有基于大块内存的可变长度内存分配方法,优点是对于字符串类似的应用提供了很好的解决方法,缺点是要自己管理碎片,相当于在系统的内存管理之上再构建一个内存管理,同样有查找合适内存快的开销;
  2 
  3 本文采用的是固定内存快的内存池,当所要求分配的内存大于快的大小时则直接交由系统分配,以后才会采用其他的方式写出内存池,采取性能最优原则,另外对于多线程还需要系统锁,也会增加开销,如何权衡需要多种方案对比才能得出结论。
  4 
  5 源代码如下,经测试直接分配达到测试的循环需求需要500毫秒左右,采用内存池在100毫秒左右
  6 
  7 
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <windows.h>
 11 #include "testStruct.h"
 12 #define BLKSIZ 80 //回收块的大小
 13 #define STKSIZ 4000 //每块内存大小
 14 
 15 struct BLOCK
 16 {
 17 char *link;
 18 char data[BLKSIZ];
 19 };
 20 static struct BLOCK * heap;
 21 static struct BLOCK * top_of_heap;
 22 static struct BLOCK * btm_of_heap;
 23 int kint=0;
 24 /*初始化*/
 25 void Init_heap()
 26 {
 27 unsigned blk;
 28 struct BLOCK *ptr;
 29 heap=(struct BLOCK *)malloc(BLKSIZ);//第一个快
 30 btm_of_heap=heap;
 31 ptr=heap;
 32 for(blk=0;blk<500;blk++)
 33 {
 34    ptr->link=(struct BLOCK *)malloc(BLKSIZ);
 35    ptr=ptr->link;
 36 }
 37 ptr->link=NULL;
 38 top_of_heap=ptr;
 39 }
 40 
 41 /*根据系统需求增加新的块*/
 42 void expendMem()
 43 {
 44 
 45 unsigned blk;
 46 struct BLOCK *ptr;
 47 heap=(struct BLOCK *)malloc(BLKSIZ);//第一个快
 48 top_of_heap=heap;
 49 ptr=heap;
 50 for(blk=0;blk<49;blk++)
 51 {
 52    ptr->link=(struct BLOCK *)malloc(BLKSIZ);
 53    ptr=ptr->link;
 54 }
 55 ptr->link=NULL;
 56 top_of_heap=ptr;
 57 kint++;
 58 printf(" %i ",kint);
 59 }
 60 
 61 /*释放一个区域的内存*/
 62 void My_Free(struct BLOCK *ptr)
 63 {
 64 if(ptr>=btm_of_heap)
 65 {
 66    if(ptr<top_of_heap)
 67    {
 68     ptr->link=heap;
 69     heap=ptr;
 70     return;
 71    }
 72    else
 73      {
 74     free(ptr);
 75     //printf("释放"); 
 76     return;
 77    }
 78 }
 79 puts("
Attempt to free blocks ");
 80 }
 81 
 82 /*申请一块内存*/
 83 
 84 void *Allocate(unsigned bytes)
 85 {
 86 void *ptr;
 87 if(bytes<=BLKSIZ)
 88 {
 89    if(heap!=NULL)
 90    {
 91     ptr=heap;
 92     heap=heap->link;
 93     return ptr;
 94    }
 95    else
 96    {
 97     expendMem();
 98    }
 99 }
100 if(ptr=malloc(bytes))
101 {
102    return ptr;
103 }
104 puts(" memory");
105 }
106 
107 /*主函数*/
108 int main()
109 {
110 int j=0;
111 int lint=0;
112 struct BLOCK *p[1000];
113     char User[20] = {"xiaoming"} ;
114    // char Password[20] = "123456";
115 
116 DWORD last,current;
117 last=GetTickCount();
118 Init_heap();
119 for(j=0;j<500;j++)
120 {
121    int i;
122    for(i=0;i<1000;i++)
123    {
124     p[i]=Allocate(20);// New(struct Login,1);
125    
126     strcpy(p[i]->data,User);
127 //   strcpy(p->Password,Password);
128    }
129    for(i=0;i<1000;i++)
130     My_Free(p[i]);
131 }
132 heap=btm_of_heap;
133 while(heap->link!=NULL)
134 {/*循环输出内存管理链表中的序列号,看看有没有断链*/
135    lint++;
136    printf("l:%i ",lint);
137    heap=heap->link;
138 }
139 current=GetTickCount();
140 printf("总共耗时 %d",current-last);
141 
142 }
原文地址:https://www.cnblogs.com/Lee-geeker/p/3354666.html