一种巧妙的内存池算法(HeapBlock)

在一个简单的GUI库中看到的算法,非常巧妙,适用于需要频繁分配和释放相同大小数据块的情况,如GUI库中的窗口结构,SOCKET结构等,算法额外开支极小。

  1. typedef DWORD HBLOCKHEAP; 
  2. typedef unsigned char BYTE, *PBYTE
  3.  
  4. //使用之前需要先分配一整块内存,并调用此函数进行初始化,初始化后将形成一个链,只是这个链没有前后指针, 
  5. //指针数据保存在数据块实体数据前4字节中 
  6. HBLOCKHEAP BlockHeap_Initialize(void* buffer, int buffersize, int blocksize) 
  7.     PBYTE pBlock = (PBYTE)buffer; 
  8.  
  9.     for(buffersize -= blocksize; pBlock - (PBYTE)buffer < buffersize ; pBlock += blocksize) 
  10.     { 
  11.              //此处将后一块的位置保存在前一块的前4字节中,(PBYTE*)pBlock的转换只是为了将pBlock暂时解释成BYTE*,才能赋值4字节内存地址 
  12.         *(PBYTE*)pBlock = pBlock + blocksize; 
  13.          } 
  14.          *(PBYTE*)pBlock = NULL;//最后一块的下一块为空块 
  15.     return (HBLOCKHEAP)buffer;//返回此链的首块,此值需要调用者保存 
  16.  
  17.  
  18. //从内存池中分配数据时,直接将链首返回给调用者,同时将链首指向的下一块指定为新的链首 
  19. void* BlockHeap_Alloc(HBLOCKHEAP* pHeap) 
  20.     void* pBlock = (void*)(*pHeap); 
  21.  
  22.     if(pBlock) 
  23.         *pHeap =(HBLOCKHEAP)( *(PBYTE*)(*pHeap) ); 
  24.  
  25.     return pBlock; 
  26.  
  27.  
  28. //释放时将要释放的块指定为新的链首,并指向原链首即可 
  29. void BlockHeap_Free(HBLOCKHEAP* pHeap, void* pBlock) 
  30.     *(PBYTE*)pBlock = (PBYTE)(*pHeap); 
  31.     *pHeap = (HBLOCKHEAP)pBlock; 
  32.  
  33.  
  34.  
  35. //基本的调用示例 
  36. typedef struct
  37.     int a; 
  38.     int b; 
  39.     int c; 
  40.     ... 
  41. }SOCKET, *PSOCKET; 
  42.  
  43.  
  44. static SOCKET s_sockets[100];    //先分配的内存 
  45. static HBLOCKHEAP s_hSockets;    //保存链首的变量 
  46.  
  47. //初始化并得到链首 
  48. s_hSockets = BlockHeap_Initialize(s_sockets, sizeof(s_sockets), sizeof(s_sockets[0])); 
  49. //分配内存 
  50. SOCKET *sock = BlockHeap_Alloc(&s_hSockets); 
  51.  
  52. //其它操作... 
  53.  
  54.  
  55. //释放内存 
  56. BlockHeap_Free(&s_hSockets, sock); 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值