b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

操作方法:固定内存池(包括代码)的实现

电脑杂谈  发布时间:2020-09-28 01:03:43  来源:网络整理

所谓的内存池是指应用程序可以通过系统的内存分配调用一次申请适当大小的内存作为内存池,然后,内存分配和应用程序本身的释放就可以通过此内存池完成。 。仅当需要动态扩展内存池的大小时,才需要再次调用系统的内存分配功能,并且其他时候对内存的所有操作都在应用程序的控制之下。

根据不同的适用方案,应用程序定义的内存池具有不同的类型。

从线程安全的角度来看,内存池可以分为单线程内存池和多线程内存池。单线程内存池在其整个生命周期中仅由一个线程使用,因此无需考虑互斥访问的问题。多线程内存池可能由多个线程共享,因此每次分配和释放内存时都必须锁定。相比之下,单线程内存池具有更高的性能,而多线程内存池具有更广泛的应用程序。

从存储池可以分为存储单元的大小,可以分为固定存储池和可变存储池。所谓的固定存储池,是指应用程序每次从存储池中分配的存储单元的大小已经预先确定并固定;而可变内存池则可以根据需要更改每次分配的内存单元的大小,应用范围更广,性能也低于固定内存池。

具体的介绍可以在这篇IBM文章中找到:

前一段时间,我有一些空闲时间,所以我写了一个基本的内存池实现。它不支持多线程,并且是固定的内存池。

如果您想参考这篇文章,可以在这里查看我的代码。

ps:非常感谢Xiao Lai帮助我调试了内存恢复错误。有时编写一段代码只需要1到2个小时,但是发现bug可能需要1天。

memory_pool.h

  1. #ifndef MEMORY_POOL_H     
  2. #define MEMORY_POOL_H     
  3.     
  4. /***********************************  
  5. * author:hairetzhang                *  
  6. * date:2009.9.1                     *  
  7. * funtion: regular memory pool lib  *  
  8. * version 1.0                       *  
  9. *                                   *  
  10. ************************************/ 
  11.     
  12. #include      
  13. #include      
  14.     
  15. using namespace std;     
  16.     
  17. #define  USHORT unsigned short     
  18. #define  ULONG  unsigned long     
  19. #define ADATAUNIT  2     
  20. #define MEMPOOL_ALIGNMENT 4       //机器的字节对齐数     
  21.     
  22.     
  23.     
  24. struct MemoryBlock     
  25. {     
  26.     MemoryBlock*  pNext;     
  27.     USHORT          nSize;        //每个block的总小块数     
  28.     USHORT          nfree_left;   //剩余小块的数目     
  29.     USHORT          nfirst_index; //第一个可用小块的索引号      
  30.     USHORT            aData[1];   //第一个小块前一个字节,不被使用     
  31.     
  32.          
  33.         //nSize = nTypes;   //记录分配的小块数     
  34.         //pNext = NULL;     
  35.     static void* block_new( USHORT nTypes, USHORT nUnitSize)     
  36.     {     
  37.         MemoryBlock*  my_block;     
  38.         my_block = (MemoryBlock *) malloc(sizeof(MemoryBlock) + nTypes * nUnitSize);     
  39.         cout << "sizeof block is :" << sizeof(MemoryBlock) <
  40.         my_block->nSize = nTypes;    //申请时,块内初始化     
  41.         my_block->nfree_left = nTypes;     
  42.         my_block->nfirst_index = 0;     
  43.         my_block->pNext = NULL;     
  44.         return my_block;     
  45.     
  46.     }     
  47.     static void  block_delete(void *p )     
  48.     {     
  49.         free(p);     
  50.     }     
  51.     MemoryBlock (USHORT nTypes = 1, USHORT nUnitSize = 0);     
  52.     ~MemoryBlock();     
  53. };     
  54.     
  55.     
  56. class MemoryPool     
  57. {     
  58. private:     
  59.     MemoryBlock*   pBlock;     
  60.     USHORT          nUnitSize;     
  61.     USHORT          nInitSize;     
  62.     USHORT          nGrowSize;     
  63.     
  64. public:     
  65.                      MemoryPool( USHORT nUnitSize,     
  66.                                   USHORT nInitSize = 1024,     
  67.                                   USHORT nGrowSize = 256 );     
  68.                     ~MemoryPool();     
  69.     
  70.     void*           Alloc();     
  71.     void            Free( void* p );                                  
  72.     void            init_block(MemoryBlock* new_block , USHORT nSize);     
  73.     void*           get_pblock();  //用于调试     
  74. };  
  75. #endif   

memory_pool.cpp

  1. #include "stdafx.h"  
  2. #include   
  3. #include   
  4. #include "memory_pool.h"  
  5.  
  6. using namespace std;  
  7.  
  8. MemoryPool::MemoryPool( USHORT _nUnitSize,  
  9.               USHORT _nInitSize, USHORT _nGrowSize )  
  10. {  
  11.     pBlock      = NULL;                 
  12.     nInitSize   = _nInitSize;  //每个块分配的索引小块数     
  13.     nGrowSize   = _nGrowSize;  //增长块的内存索引小块数     
  14.     
  15.     //设置小块的大小     
  16.     if ( _nUnitSize > 4 )                         
  17.         nUnitSize = (_nUnitSize + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);      
  18.     else if ( _nUnitSize <= 2 )     
  19.         nUnitSize = 2;                   
  20.     else    
  21.         nUnitSize = 4;     
  22. }     
  23.     
  24.     
  25. //初始化分配的新块,nSize为该块的总索引数
  26. void   MemoryPool::init_block( MemoryBlock* new_block ,USHORT nSize )      
  27. {//从第二个小块开始设置索引,第一个小块返回提供使用
  28.     char *pdata = (char * )new_block->aData;      
  29.     USHORT *mini_block_head;     
  30.     for(int i = 1 ;i < nSize; ++i)         
  31.     { //设置每个小块的索引头,0号返回给该次申请者使用
  32.         mini_block_head = (USHORT *)(pdata+nUnitSize*i +ADATAUNIT);     
  33.         *mini_block_head = i+1;     
  34.     }     
  35.     new_block->nfirst_index = 1;     
  36.     new_block->nfree_left = nSize-1;     
  37. }     
  38.     
  39. void* MemoryPool::Alloc()     
  40. {     
  41.     if( !pBlock )  //当前内存池尚无内存块,第一次分配     
  42.     {     
  43.         pBlock = (MemoryBlock *) MemoryBlock::block_new (nInitSize, nUnitSize);
  44.         init_block( pBlock ,nInitSize);     
  45.         return (void *) (pBlock->aData+1);     
  46.     }
  47.     
  48.     MemoryBlock* pMyBlock = pBlock; //从链表头部pBlock开始
  49.     while (pMyBlock && !pMyBlock->nfree_left ) //搜索可用内存快
  50.         pMyBlock = pMyBlock->pNext;
  51.  
  52.     if ( pMyBlock )  //尚有可用的内存快     
  53.     {
  54.         char* pFree = (char *) ( (ULONG)pMyBlock->aData+
  55. ( pMyBlock->nfirst_index*nUnitSize)+ADATAUNIT );
  56.         printf("pMyBlock->aData:%p, pFree:%p\n",pMyBlock->aData,pFree);
  57.         pMyBlock->nfirst_index = *( (USHORT *)pFree );//每小块的头部两字节记录了下一个可用索引号
  58.         pMyBlock->nfree_left--;
  59.         return (void*)pFree;
  60.     }
  61.     else    //找不到可用内存块     
  62.     {     
  63.         if ( !nGrowSize )     
  64.             return NULL;     
  65.         pMyBlock = (MemoryBlock *)MemoryBlock::block_new (nGrowSize, nUnitSize);
  66.         if ( !pMyBlock )     
  67.             return NULL;     
  68.     
  69.         pMyBlock->pNext = pBlock; //新块插入到块链表头部
  70.         pBlock = pMyBlock;     
  71.     
  72.         init_block( pMyBlock ,nGrowSize);     
  73.     
  74.         return (void*)(pMyBlock->aData+ADATAUNIT);     
  75.     }     
  76. }     
  77.     
  78.     
  79. void MemoryPool::Free( void* pFree )     
  80. {     
  81.     USHORT* pfree_us;        
  82.     USHORT pfree_index, pHead;     
  83.     pfree_us = (USHORT *)pFree;     
  84.     MemoryBlock* pMyBlock = pBlock;     
  85.     MemoryBlock* pre_pBlock = NULL;     
  86.     
  87.     while ( ((ULONG)pMyBlock->aData > (ULONG)pfree_us) ||
  88.          ((ULONG)pfree_us >= 
  89. ((ULONG)pMyBlock->aData + pMyBlock->nSize*nUnitSize)))
  90.        //定位pFree所在的块     
  91.     {     
  92.          pre_pBlock = pMyBlock;     
  93.          pMyBlock = pMyBlock->pNext;     
  94.     }     
  95.     if(pMyBlock == NULL) //pFree不是属于内存池管理的内存
  96.         return;
  97.     
  98.     //回收pFree
  99.     pMyBlock->nfree_left++;
  100.     pHead = pMyBlock->nfirst_index;  //第一个可用索引
  101.     pfree_index = ( (ULONG)pfree_us-(ULONG)pMyBlock->aData -ADATAUNIT)/nUnitSize;
  102. //获取pFree的索引号     
  103.     pMyBlock->nfirst_index = pfree_index;  //pFree插入到可用块首
  104.     *pfree_us = pHead;  //之前的块首链入
  105.           
  106.     //判断是否需要将Block内存返回给系统
  107.      if (pMyBlock->nfree_left  == pMyBlock->nSize )                           
  108.     {     
  109.         if(pre_pBlock)   //删除的不是第一个MemoryBlock
  110.             pre_pBlock->pNext = pMyBlock->pNext;
  111.         pBlock = pMyBlock->pNext;//删除的是第一个MemoryBlock
  112.         MemoryBlock::block_delete(pMyBlock);     
  113.     }     
  114.     
  115. }     
  116.     
  117. MemoryPool::~MemoryPool()     //析构函数释放所有的MemoryBlock,即使用户忘记free掉自己申请的内存也不会发生内存泄漏     
  118. {     
  119.     MemoryBlock*   my_block = pBlock;     
  120.     MemoryBlock*   next_block = NULL;     
  121.     while( my_block )     
  122.     {     
  123.         next_block = my_block->pNext;     
  124.         MemoryBlock::block_delete( (void *)my_block);     
  125.         my_block = next_block;     
  126.     }     
  127. }     
  128.     
  129. void* MemoryPool::get_pblock()     
  130. {     
  131.     return pBlock;     

(hairetz)


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-322404-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 谭嗣同
        谭嗣同

        晚上你直接去他家就可以了

      • 丁求安
        丁求安

        随着排水量达12000吨的055型驱逐舰的建造服役

      热点图片
      拼命载入中...