经典数据结构之内存池技术

一般来说,使用堆来动态分配内存是常用的方式。然而,如果不断申请堆,会造成内存碎片,以至于由于堆本身大小的限制,难以再申请出连续空间的堆,显然造成了内存利用不合理。所以,有必要对内存申请进行一些管理。对于大型程序来说,很必要,提前申请一定量的堆,一定比不断申请快很多。使用数组方式,可以很快检索到可用的空间,并O(1)进行存取,而节点做成链表结构,更可以在O(1)释放某个空间之后找到合适的节点进行分配。

代码如下:

#ifndef SPACEPOOL_HHH 
#define SPACEPOOL_HHH
//declaration;

template<typename T>
class CSpacePool;


template<typename T>
struct SPoolNode{
	// members;
private:
    T m_nData;
    int m_nNextIndex;
public:
	// constructors;
	friend class CSpacePool<T>;
};  //SPoolNode;

template<typename T>
class CSpacePool{
private:
	// members;
	int m_nSpaceSize;            // max number of nodes could be allocated;
	int m_nFirstUseableIndex;    // the first useable node.
	SPoolNode<T>* m_pNode;       // data table;
public:
	// constructors;
    CSpacePool(int maxsize);
	~CSpacePool();

	// methods;
	int mAllocate();             // allocate a space;
    void mDeAllocate(int& i);    // deallocate the (i+1)th node;
};  // CSpacePool;


// de-constructors;
template<typename T>
CSpacePool<T>::CSpacePool(int maxsize = 100){
	m_nSpaceSize = maxsize;
	m_pNode = new SPoolNode<T>[m_nSpaceSize];

	for(int i = 0; i < m_nSpaceSize - 1; i ++){
		m_pNode[i].m_nNextIndex = i + 1;
	}
    m_pNode[m_nSpaceSize - 1].m_nNextIndex = -1;    
	m_nFirstUseableIndex = 0;
}

template<typename T>
CSpacePool<T>::~CSpacePool(){
    delete[] m_pNode;
}

template<typename T>
int CSpacePool<T>::mAllocate(){
    if(-1 == m_nFirstUseableIndex){
		printf("Space is full, Cannot alloc\n");
	    return -1;
    }else{
		int ret = m_nFirstUseableIndex;
		m_nFirstUseableIndex = m_pNode[m_nFirstUseableIndex].m_nNextIndex;
		return m_nFirstUseableIndex;
	}
}

template<typename T>
void CSpacePool<T>::mDeAllocate(int& i){
    m_pNode[i].m_nNextIndex = m_nFirstUseableIndex;
	m_nFirstUseableIndex = i;
	i = -1;
}
#endif

测试代码如下:

#include "SimulatePointer.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(){
	CSpacePool<int> pool(100);
	for(int i = 0; i < 101; i ++)
		pool.mAllocate();
	for(int i = 0; i < 101; i ++){
		int m = i;
		pool.mDeAllocate(m);
	}
    system("pause");
	return 0;
}

结果如下:

Space is full, Cannot alloc
请按任意键继续. . .

上述是最简单的内存池技术,实际上内存管理比这个复杂很多,但基本思想一致。事实上,在现在的大型程序里面,池技术是一个很重要的话题,例如线程池,进程池等资源池。它们能够有效避免多次分配带来的内核交互代价,进而加快程序速度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值