在一个简单的GUI库中看到的算法,非常巧妙,适用于需要频繁分配和释放相同大小数据块的情况,如GUI库中的窗口结构,SOCKET结构等,算法额外开支极小。
- typedef DWORD HBLOCKHEAP;
- typedef unsigned char BYTE, *PBYTE;
- //使用之前需要先分配一整块内存,并调用此函数进行初始化,初始化后将形成一个链,只是这个链没有前后指针,
- //指针数据保存在数据块实体数据前4字节中
- HBLOCKHEAP BlockHeap_Initialize(void* buffer, int buffersize, int blocksize)
- {
- PBYTE pBlock = (PBYTE)buffer;
- for(buffersize -= blocksize; pBlock - (PBYTE)buffer < buffersize ; pBlock += blocksize)
- {
- //此处将后一块的位置保存在前一块的前4字节中,(PBYTE*)pBlock的转换只是为了将pBlock暂时解释成BYTE*,才能赋值4字节内存地址
- *(PBYTE*)pBlock = pBlock + blocksize;
- }
- *(PBYTE*)pBlock = NULL;//最后一块的下一块为空块
- return (HBLOCKHEAP)buffer;//返回此链的首块,此值需要调用者保存
- }
- //从内存池中分配数据时,直接将链首返回给调用者,同时将链首指向的下一块指定为新的链首
- void* BlockHeap_Alloc(HBLOCKHEAP* pHeap)
- {
- void* pBlock = (void*)(*pHeap);
- if(pBlock)
- *pHeap =(HBLOCKHEAP)( *(PBYTE*)(*pHeap) );
- return pBlock;
- }
- //释放时将要释放的块指定为新的链首,并指向原链首即可
- void BlockHeap_Free(HBLOCKHEAP* pHeap, void* pBlock)
- {
- *(PBYTE*)pBlock = (PBYTE)(*pHeap);
- *pHeap = (HBLOCKHEAP)pBlock;
- }
- //基本的调用示例
- typedef struct{
- int a;
- int b;
- int c;
- ...
- }SOCKET, *PSOCKET;
- static SOCKET s_sockets[100]; //先分配的内存
- static HBLOCKHEAP s_hSockets; //保存链首的变量
- //初始化并得到链首
- s_hSockets = BlockHeap_Initialize(s_sockets, sizeof(s_sockets), sizeof(s_sockets[0]));
- //分配内存
- SOCKET *sock = BlockHeap_Alloc(&s_hSockets);
- //其它操作...
- //释放内存
- BlockHeap_Free(&s_hSockets, sock);