c++内存池

总体思想:首先申请一大块内存,在将其分割为一个个小的单元,每一个单元的起始位置放置着用于管理内存块的双向链表结点。剩余位置放置用户数据。

这里写图片描述

#include<iostream>
#include<Windows.h>



class CMemPool
{
private:
    struct _Unit
    {
        _Unit*pPre;
        _Unit*pNext;
    };

    void * m_pMemPool;//address of memory pool

    //two linked list 
    _Unit* m_pAllocatedMemBlock;// used memory blocks
    _Unit* m_pFreeMemBlock;//free memory blocks

    unsigned long m_ulUnitSize;
    unsigned long m_ulMemPoolSize;

    CMemPool(const CMemPool&);
    CMemPool& operator = (const CMemPool&);
public:
    CMemPool(unsigned long ulUnitNum = 1000, unsigned long ulUnitSize = sizeof(int));
    ~CMemPool();
    void* Alloc(unsigned long ulSize);
    void Free(void*p);

};


CMemPool::CMemPool(unsigned long ulUnitNum, unsigned long ulUnitSize)
{
    m_ulUnitSize = ulUnitSize;
    m_ulMemPoolSize = ulUnitNum*(ulUnitSize + sizeof(_Unit));

    m_pMemPool = malloc(m_ulMemPoolSize); //allocate a memory pool

    if (NULL != m_pMemPool)
    {
        for (unsigned long i = 0; i < ulUnitNum; ++i)
        {
            ///void 指针不能进行算术计算  所以计算地址时将m_pMemPool 转换为char
            _Unit* pCurrUnit = (_Unit*)((char*)m_pMemPool + i*(ulUnitSize + sizeof(_Unit)));
            pCurrUnit->pNext = m_pFreeMemBlock;
            pCurrUnit->pPre = NULL;

            if (NULL != m_pFreeMemBlock)
            {
                m_pFreeMemBlock->pPre = pCurrUnit;
            }
            m_pFreeMemBlock = pCurrUnit;
        }
    }
    else
    {
        std::cout << "malloc pool memeory failure!" << std::endl;
    }

}
CMemPool::~CMemPool()
{
    free(m_pMemPool);
}

void* CMemPool::Alloc(unsigned long ulSize)
{
    if (m_pFreeMemBlock != NULL)
    {
        _Unit* pTemp = m_pFreeMemBlock;

        if (pTemp->pNext != NULL)
        {
            pTemp->pNext->pPre = NULL;
        }
        m_pFreeMemBlock = m_pFreeMemBlock->pNext;

        pTemp->pNext = m_pAllocatedMemBlock;
        if (m_pAllocatedMemBlock != NULL)
        {
            m_pAllocatedMemBlock->pPre = pTemp;
        }
        m_pAllocatedMemBlock = pTemp;

        return ((char*)(m_pAllocatedMemBlock)+sizeof(_Unit));
    }
    else
        return malloc(ulSize);
}

///将待释放的内存结点插入m_pFreeMemBlock链表中
void CMemPool::Free(void*p)
{
    if (p > m_pMemPool && p < (void*)((char*)m_pMemPool + m_ulMemPoolSize))//p在当前内存池范围内
    {
        _Unit* pCurrUnit = (_Unit*)((char*)p - sizeof(_Unit));
        if (pCurrUnit->pNext != NULL)
        {
            pCurrUnit->pNext->pPre = pCurrUnit->pPre;
        }
        if (pCurrUnit->pPre != NULL)
        {
            pCurrUnit->pPre->pNext = pCurrUnit->pNext;
        }
        else if (pCurrUnit->pPre == NULL)//当前结点是已分配内存的头结点
        {
            m_pAllocatedMemBlock = pCurrUnit->pNext;
        }

        pCurrUnit->pNext = m_pFreeMemBlock;
        if (m_pFreeMemBlock != NULL)
        {
            m_pFreeMemBlock->pPre = pCurrUnit;
        }
        m_pFreeMemBlock = pCurrUnit;
        pCurrUnit->pPre = NULL;

    }
    else
    {
        free(p);
    }
}

参考资料
Why to use memory pool and how to implement it

猜你喜欢

转载自blog.csdn.net/werweqg/article/details/44890877