zoukankan      html  css  js  c++  java
  • 【链表】关于链表的内存池

      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 }
  • 相关阅读:
    PyQt QFontDialog显示中文
    zetcode :: First programs in PyQt5
    PyQt4 初试牛刀二
    PyQt5实现透明电子时钟
    配置web.xml和glassfish容器实现javaEE表单验证
    nodejs querystring踩坑笔记----只能用于表单提交
    使用JavaEE的ServerAuthModule模块和web.xml进行相应配置,实现对用户的权限控制
    CAS单点登录(SSO)服务端的部署和配置---连接MySQL进行身份认证
    Oracle中碰到的函数和关键字收集
    windows系统局域网内开启远程桌面图解
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3354666.html
Copyright © 2011-2022 走看看