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("\nAttempt 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 }