C++实现内存池

想用C++实现内存池,参考了一下别人的代码
http://blog.csdn.net/chexlong/article/details/7071922
人家对内存块的管理是用vector,动态的插入与删除,来做内存的分配与回收,基于人家的代码,做的一些改动,用Map进行管理,用标志来区分该内存块是否已分配,回收时,内存里面的内容也得重置掉,以免影响下一次的调用。
代码如下


#ifndef _MEM_POOL_H
#define _MEM_POOL_H

#include <vector>
#include <iostream>
#include <map>
#include "string.h"


using namespace std;

/*
在内存池中分配固定大小的内存块

该类的目的是加速内存分配速度,并且减少因重复分配相同
内存时产生的内存碎片,比如在服务器应用程序中。
*/

struct sBlock
{
    short   isHasUse; // 是否使用过
    int     iIndx;    // 编号
    char*   pBlock;   // 内存块所指向的地址
};

class CMemPool
{
public:

    //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc
    CMemPool(std::size_t blockSize, int preAlloc = 0);

    ~CMemPool();

    //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块
    //如果分配的内存块数目达到了最大值,则会返回一个异常
    void* Get();

    //释放当前内存块,将其插入内存池
    void Release(void* ptr);

    //返回内存块大小
    std::size_t BlockSize() const;

    //返回内存池中内存块数目
    int Allocated() const;

    //返回内存池中可用的内存块数目
    int Available() const;

    //得到内存块的数量
    int GetBlockNum() const;

private:
    CMemPool();
    CMemPool(const CMemPool&);
    CMemPool& operator = (const CMemPool&);

    enum
    {
        BLOCK_RESERVE = 32
    };

    typedef std::vector<char*> BlockVec;

    std::size_t m_blockSize;
    int         m_maxAlloc;
    int         m_allocated;
    BlockVec    m_blocks;

    typedef map<int, sBlock> BlockMap;
    BlockMap    m_blocks_map;

};

inline std::size_t CMemPool::BlockSize() const
{
    return m_blockSize;
}


// 得到已经分配出去的有多少
inline int CMemPool::Allocated() const
{
    int iTotalUseNum = 0;
    for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
    {
        if (it->second.isHasUse == 1)
        {
            iTotalUseNum += 1;
        }
    }
    return iTotalUseNum;
}

inline int CMemPool::Available() const
{
    int iAvailableNum = 0;
    for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
    {
        if (it->second.isHasUse == 0)
        {
            iAvailableNum += 1;
        }
    }
    return iAvailableNum;
}

inline int CMemPool::GetBlockNum() const
{
    return m_blocks_map.size();
}

CMemPool::CMemPool(std::size_t blockSize, int preAlloc) :
m_blockSize(blockSize),
m_allocated(preAlloc)
{
    m_blocks_map.clear();
    for (int i = 0; i < preAlloc; ++i)
    {
        sBlock nBlock;
        nBlock.isHasUse = 0;
        nBlock.iIndx = i;
        nBlock.pBlock = new char[m_blockSize];
        m_blocks_map[i] = nBlock;
    }

}

CMemPool::~CMemPool()
{
    for (BlockMap::iterator it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
    {

        cout << " delete the block indx = " << it->second.iIndx << "  " << endl;
        delete[] it->second.pBlock; // 删除内存对应的内存空间
    }
    m_blocks_map.clear();
}


void* CMemPool::Get()
{
     // 分配内存地址
    for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
    {
        if (it->second.isHasUse == 0)
        {
            it->second.isHasUse = 1; // 表示该内存块已经被分配出去了
            cout << " this block indx = " << it->second.iIndx << "  has be used " << endl;
            return it->second.pBlock;
        }
    }

    // 如果内存map 都被用完啦,那么则得添加新的内存块到map中
    auto iter = m_blocks_map.end();
    iter--; // 得往后减一个,才能取到最后一个元素

    int maxIndx = iter->second.iIndx;

    int curIndx = maxIndx + 1;
    sBlock nBlock;
    nBlock.iIndx = curIndx;
    nBlock.isHasUse = 0;
    nBlock.pBlock = new char[m_blockSize];
    m_blocks_map[curIndx] = nBlock;

    // 将新添加的分配出来用
    m_blocks_map[curIndx].isHasUse = 1;
    cout << " this block indx = " << m_blocks_map[curIndx].iIndx << " create and  has be used " << endl;
    return m_blocks_map[curIndx].pBlock;

}


void CMemPool::Release(void* ptr)
{
    for (auto it = m_blocks_map.begin(); it != m_blocks_map.end(); ++it)
    {
        char * pTmp = reinterpret_cast<char*>(ptr);
        if (it->second.pBlock == pTmp)
        {
            cout << " the block indx = " << it->second.iIndx << "   has be Released " << endl;
            it->second.isHasUse = 0;
            memset(pTmp, 0, m_blockSize);
        }
    }
}


#endif

测试代码

#include "MemPool.h"

#define DATA_BLOCK_LEN 50

struct  sTest
{
    int m_id;
    int m_num;
};

struct  sTest2
{
    int m_id;
    int m_num;
    char m_str[10];
};

int main()
{
    CMemPool myPool1(DATA_BLOCK_LEN, 20);

    cout << "myPool1 block size = " << myPool1.BlockSize() << endl;
    cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
    cout << "myPool1 available block num = " << myPool1.Available() << endl;
    cout << "myPool1 total block num = " << myPool1.GetBlockNum() << endl <<endl;

    // 分配一个内存块
    struct sTest* pTest;
    pTest = (struct sTest*)(myPool1.Get());

    pTest->m_id = 25;
    pTest->m_num = 10000;
    cout << pTest->m_id <<"  " <<pTest->m_num << endl;

    struct sTest* pTest2;
    pTest2 = (struct sTest*)(myPool1.Get());

    pTest2->m_id = 123;
    pTest2->m_num = 13445;
    cout << pTest2->m_id << "  " << pTest2->m_num << endl << endl;


    cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
    cout << "myPool1 available block num = " << myPool1.Available() << endl << endl;

    // 回收该内存块
    myPool1.Release(pTest);
    pTest = NULL;

    cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
    cout << "myPool1 available block num = " << myPool1.Available() << endl << endl;

    //pTest = (struct sTest*)(myPool1.Get());
    //cout << pTest->m_id << endl;
    //cout << pTest->m_num << endl;
    struct sTest2* pTtmp;
    pTtmp = (struct sTest2*)(myPool1.Get());
    pTtmp->m_id = 1234;
    char * cTmp= "skskdlsl";
    memcpy(pTtmp->m_str, cTmp, strlen(cTmp));
    cout << pTtmp->m_str << endl;

    cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
    cout << "myPool1 available block num = " << myPool1.Available() << endl << endl;

    myPool1.Release(pTtmp);

    for (int i = 0; i < 30; ++i)
    {
        struct sTest* pTest3;
        pTest3 = (struct sTest*)(myPool1.Get());

        pTest3->m_id = 123;
        pTest3->m_num = 13445;
        cout << pTest3->m_id << "  " << pTest3->m_num << endl << endl;
        cout << "myPool1 allocated block num = " << myPool1.Allocated() << endl;
        cout << "myPool1 available block num = " << myPool1.Available() << endl;
        cout << "myPool1 total block num = " << myPool1.GetBlockNum() << endl << endl;
    }

    int iWait;
    cin >> iWait;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值