c++ 实现内存池

转载于:http://blog.youkuaiyun.com/chexlong/article/details/7071922


     打开浏览器,搜索了下内存管理的概念,百度百科中是这样定义的:内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。说到内存,与之紧密相联系的一个概念就是指针。回想起上学那会儿,自己对指针是即喜欢,又害怕。因为学好了指针,就可以学好C,继而学好C++,但面对那些晦涩的概念,和程序运行中一些莫名其妙的指针越界、内存泄露……,不免叫人步步惊心。后来参加工作了,在不断的摸爬滚打中,也逐渐对指针和内存熟悉起来。

    在编写网络通信程序时,要用到自己的发送缓冲区或接收缓冲区,其实这些缓冲区,都是一块特定的内存。特别在编写服务端程序时,能否管理好自己的内存,对于程序的灵活,高效,稳定,起到莫大的作用。再看一下内存管理的定义,它说的是在PC上,现实中也有很多程序不在PC上,比如基于Linux系统的嵌入式设备。其内存一般也就几M,几十M的样子。在编写设备通信程序,比如协议栈时,就更应该管理好自己的内存啦!

    下边,我参考开源项目POCO C++ Libraries,用C++编写了一个内存池类,也算是对学习和工作的一个总结,同时方便今后使用。代码中使用了线程互斥锁,这个可以在互斥对象锁和临界区锁性能比较(Win32)和Linux平台上用C++实现多线程互斥锁看到。以下代码已在VS2005环境下编译通过。

 Lock.h


#pragma once
#ifndef _LOCK_H
#define _LOCK_H

#include <windows.h>

//接口类
class IMyLock
{
public:
	virtual ~IMyLock(){}

	virtual void Lock() const=0;
	virtual void UnLock() const =0;
};
class CMutex :public IMyLock
{
public:
	CMutex(void);
	~CMutex(void);

	void Lock() const;
	void UnLock() const ;

private:
	HANDLE m_mutex;
};


//锁

class CLock
{
public:
	CLock(const IMyLock&);
	~CLock();
private:
	const IMyLock& m_lock;
};

#endif

Lock.cpp

#include "stdafx.h"
#include "lock.h"


CMutex::CMutex()
{
	m_mutex=::CreateMutex(NULL,FALSE,NULL);
}

CMutex::~CMutex()
{
	if (m_mutex)
	{
		::CloseHandle(m_mutex);
	}
}


void CMutex::Lock() const
{
	DWORD dw=WaitForSingleObject(m_mutex,INFINITE);
}

void CMutex::UnLock() const
{
	::ReleaseMutex(m_mutex);
}

CLock::CLock(const IMyLock& m):m_lock(m)
{
	m_lock.Lock();
}

CLock::~CLock()
{
	m_lock.UnLock();
}



MemPool.h

[cpp]   view plain copy
  1. #ifndef _MEM_POOL_H  
  2. #define _MEM_POOL_H  
  3.   
  4. #include <vector>  
  5. #include <iostream>  
  6. #include "Lock.h"  
  7.   
  8. using namespace std;  
  9.   
  10. /* 
  11.     在内存池中分配固定大小的内存块 
  12.  
  13.     该类的目的是加速内存分配速度,并且减少因重复分配相同 
  14.     内存时产生的内存碎片,比如在服务器应用程序中。 
  15. */  
  16.   
  17. class CMemPool  
  18. {  
  19. public:  
  20.   
  21.     //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc  
  22.     CMemPool(std::size_t blockSize, int preAlloc = 0, int maxAlloc = 0);  
  23.   
  24.     ~CMemPool();  
  25.   
  26.     //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块  
  27.     //如果分配的内存块数目达到了最大值,则会返回一个异常  
  28.     void* Get();  
  29.   
  30.     //释放当前内存块,将其插入内存池  
  31.     void Release(void* ptr);  
  32.   
  33.     //返回内存块大小  
  34.     std::size_t BlockSize() const;  
  35.   
  36.     //返回内存池中内存块数目  
  37.     int Allocated() const;  
  38.   
  39.     //返回内存池中可用的内存块数目  
  40.     int Available() const;  
  41.   
  42. private:  
  43.     CMemPool();  
  44.     CMemPool(const CMemPool&);  
  45.     CMemPool& operator = (const CMemPool&);  
  46.   
  47.     enum  
  48.     {  
  49.         BLOCK_RESERVE = 32  
  50.     };  
  51.   
  52.     typedef std::vector<char*> BlockVec;  
  53.   
  54.     std::size_t m_blockSize;  
  55.     int         m_maxAlloc;  
  56.     int         m_allocated;  
  57.     BlockVec    m_blocks;  
  58.     CMutex      m_mutex;  
  59. };  
  60.   
  61. inline std::size_t CMemPool::BlockSize() const  
  62. {  
  63.     return m_blockSize;  
  64. }  
  65.   
  66.   
  67. inline int CMemPool::Allocated() const  
  68. {  
  69.     return m_allocated;  
  70. }  
  71.   
  72.   
  73. inline int CMemPool::Available() const  
  74. {  
  75.     return (int) m_blocks.size();  
  76. }  
  77.   
  78.   
  79. #endif  

 

MemPool.cpp

[cpp]   view plain copy
  1. #include "MemPool.h"  
  2.   
  3. CMemPool::CMemPool(std::size_t blockSize, int preAlloc, int maxAlloc):  
  4. m_blockSize(blockSize),  
  5. m_maxAlloc(maxAlloc),  
  6. m_allocated(preAlloc)  
  7. {  
  8.     if ( preAlloc < 0 || maxAlloc == 0 || maxAlloc < preAlloc )  
  9.     {  
  10.         cout<<"CMemPool::CMemPool parameter error."<<endl;  
  11.     }  
  12.   
  13.     int r = BLOCK_RESERVE;  
  14.     if (preAlloc > r)  
  15.         r = preAlloc;  
  16.     if (maxAlloc > 0 && maxAlloc < r)  
  17.         r = maxAlloc;  
  18.     m_blocks.reserve(r);  
  19.     for (int i = 0; i < preAlloc; ++i)  
  20.     {  
  21.         m_blocks.push_back(new char[m_blockSize]);  
  22.     }  
  23. }  
  24.   
  25.   
  26. CMemPool::~CMemPool()  
  27. {  
  28.     for (BlockVec::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it)  
  29.     {  
  30.         delete [] *it;  
  31.     }  
  32. }  
  33.   
  34.   
  35. void* CMemPool::Get()  
  36. {  
  37.     CLock lock(m_mutex);  
  38.   
  39.     if (m_blocks.empty())  
  40.     {  
  41.         if (m_maxAlloc == 0 || m_allocated < m_maxAlloc)  
  42.         {  
  43.             ++m_allocated;  
  44.             return new char[m_blockSize];  
  45.         }  
  46.         else  
  47.         {  
  48.             cout<<"CMemPool::get CMemPool exhausted."<<endl;  
  49.             return (void *)NULL;  
  50.         }  
  51.     }  
  52.     else  
  53.     {  
  54.         char* ptr = m_blocks.back();  
  55.         m_blocks.pop_back();  
  56.         return ptr;  
  57.     }  
  58. }  
  59.   
  60.   
  61. void CMemPool::Release(void* ptr)  
  62. {  
  63.     CLock lock(m_mutex);  
  64.   
  65.     m_blocks.push_back(reinterpret_cast<char*>(ptr));  
  66. }  

 

    下边是测试代码

[cpp]   view plain copy
  1. // CMyMemPool.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "MemPool.h"  
  6.   
  7. #define DATA_BLOCK_LEN 1500  
  8.   
  9. int _tmain(int argc, _TCHAR* argv[])  
  10. {  
  11.     CMemPool myPool1(DATA_BLOCK_LEN, 0, 10);  
  12.   
  13.     cout<<"myPool1 block size = "<<myPool1.BlockSize()<<endl;  
  14.     cout<<"myPool1 allocated block num = "<<myPool1.Allocated()<<endl;  
  15.     cout<<"myPool1 available block num = "<<myPool1.Available()<<endl<<endl;  
  16.   
  17.     std::vector<void*> ptrs;  
  18.     for (int i = 0; i < 10; ++i)  
  19.     {  
  20.         ptrs.push_back(myPool1.Get());  
  21.     }  
  22.   
  23.     myPool1.Get();  
  24.   
  25.     int iavilable = 0;  
  26.     for (std::vector<void*>::iterator it = ptrs.begin(); it != ptrs.end(); ++it)  
  27.     {  
  28.         myPool1.Release(*it);  
  29.         ++iavilable;  
  30.         cout<<"myPool1 available block num = "<<myPool1.Available()<<endl;  
  31.     }  
  32.   
  33.     CMemPool myPool2(DATA_BLOCK_LEN, 5, 10);  
  34.     cout<<endl<<"myPool2 block size = "<<myPool2.BlockSize()<<endl;  
  35.     cout<<"myPool2 allocated block num = "<<myPool2.Allocated()<<endl;  
  36.     cout<<"myPool2 available block num = "<<myPool2.Available()<<endl;  
  37.   
  38.     int iWait;  
  39.     cin>>iWait;  
  40.   
  41.     return 0;  
  42. }  


    编译,运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值