C++ 内存池实现 并管理内存池(支持多线程)

Alloctor.h:

#ifndef _ALLOCTOR_H_
#define _ALLOCTOR_H_

void* operator new(size_t size);

void operator delete(void* p);

void* operator new[](size_t size);

void operator delete[](void* p);

void* mem_alloc(size_t size);

void mem_free(void* p);
#endif
 

Alloctor.cpp
#include"Alloctor.h"
#include"MemoryMgr.hpp"

void* operator new(size_t nSize)
{
    return MemoryMgr::Instance().allocMem(nSize);
}

void operator delete(void* p)
{
    MemoryMgr::Instance().freeMem(p);
}

void* operator new[](size_t nSize)
{
    return MemoryMgr::Instance().allocMem(nSize);
}

void operator delete[](void* p)
{
    MemoryMgr::Instance().freeMem(p);
}

void* mem_alloc(size_t size)
{
    return malloc(size);
}

void mem_free(void* p)
{
    free(p);
}

MemoryMgr.hpp

#ifndef _MemoryMgr_hpp_
#define _MemoryMgr_hpp_
#include<stdlib.h>
#include<assert.h>
#include <mutex>

#ifdef _DEBUG
#include<stdio.h>
#define xPrintf(...) printf(__VA_ARGS__)
#else
#define xPrintf(...)
#endif // _DEBUG


#define MAX_MEMORY_SZIE 128

class MemoryAlloc;
//内存块 最小单元
class MemoryBlock
{
public:
    //所属大内存块(池)
    MemoryAlloc* pAlloc;
    //下一块位置
    MemoryBlock* pNext;
    //内存块编号
    int nID;
    //引用次数
    int nRef;
    //是否在内存池中
    bool bPool;
private:
    //预留
    char c1;
    char c2;
    char c3;
};

//内存池
class MemoryAlloc
{
public:
    MemoryAlloc()
    {
        _pBuf = nullptr;
        _pHeader = nullptr;
        _nSzie = 0;
        _nBlockSzie = 0;
    }

    ~MemoryAlloc()
    {
        if (_pBuf)
            free(_pBuf);
    }

    //申请内存
    void* allocMemory(size_t nSize)
    {
        std::lock_guard<std::mutex> lock(_mutex);
        if (!_pBuf)
        {
            initMemory();
        }

        MemoryBlock* pReturn = nullptr;
        if (nullptr == _pHeader)
        {
            pReturn = (MemoryBlock*)malloc(nSize + sizeof(MemoryBlock));
            pReturn->bPool = false;
            pReturn->nID = -1;
            pReturn->nRef = 1;
            pReturn->pAlloc = nullptr;
            pReturn->pNext = nullptr;
        }
        else {
            pReturn = _pHeader;
            _pHeader = _pHeader->pNext;
            assert(0 == pReturn->nRef);
            pReturn->nRef = 1;
        }
        xPrintf("allocMem: %llx, id=%d, size=%d\n", pReturn, pReturn->nID, nSize);
        return ((char*)pReturn + sizeof(MemoryBlock));
    }

    //释放内存
    void freeMemory(void* pMem)
    {
        MemoryBlock* pBlock = (MemoryBlock*)((char*)pMem - sizeof(MemoryBlock));
        assert(1 == pBlock->nRef);
        
        if (pBlock->bPool)
        {
            if (--pBlock->nRef != 0)
            {
                return;
            }
            std::lock_guard<std::mutex> lock(_mutex);
            pBlock->pNext = _pHeader;
            _pHeader = pBlock;
        }
        else {
            if (--pBlock->nRef != 0)
            {
                return;
            }
            free(pBlock);  //操作系统里面有做线程安全处理的
        }
    }

    //初始化
    void initMemory()
    {    //断言
        assert(nullptr == _pBuf);
        if (_pBuf)
            return;
        //计算内存池的大小
        size_t realSzie = _nSzie + sizeof(MemoryBlock);
        size_t bufSize = realSzie*_nBlockSzie;
        //向系统申请池的内存
        _pBuf = (char*)malloc(bufSize);

        //初始化内存池
        _pHeader = (MemoryBlock*)_pBuf;
        _pHeader->bPool = true;
        _pHeader->nID = 0;
        _pHeader->nRef = 0;
        _pHeader->pAlloc = this;
        _pHeader->pNext = nullptr;
        //遍历内存块进行初始化
        MemoryBlock* pTemp1 = _pHeader;

        for (size_t n = 1; n < _nBlockSzie; n++)
        {
            MemoryBlock* pTemp2 = (MemoryBlock*)(_pBuf + (n* realSzie));
            pTemp2->bPool = true;
            pTemp2->nID = n;
            pTemp2->nRef = 0;
            pTemp2->pAlloc = this;
            pTemp2->pNext = nullptr;
            pTemp1->pNext = pTemp2;
            pTemp1 = pTemp2;
        }
    }
protected:
    //内存池地址
    char* _pBuf;
    //头部内存单元
    MemoryBlock* _pHeader;
    //内存单元的大小
    size_t _nSzie;
    //内存单元的数量
    size_t _nBlockSzie;
    std::mutex _mutex;
};

//便于在声明类成员变量时初始化MemoryAlloc的成员数据
template<size_t nSzie, size_t nBlockSzie>
class MemoryAlloctor :public MemoryAlloc
{
public:
    MemoryAlloctor()
    {
        //8 4   61/8=7  61%8=5
        const size_t n = sizeof(void*);
        //(7*8)+8 
        _nSzie = (nSzie / n)*n + (nSzie % n ? n : 0);
        _nBlockSzie = nBlockSzie;
    }

};

//内存管理工具
class MemoryMgr
{
private:
    MemoryMgr()
    {
        //init_szAlloc(0, 64, &_mem64);
        init_szAlloc(65, 128, &_mem128);
        //init_szAlloc(129, 256, &_mem256);
        //init_szAlloc(257, 512, &_mem512);
        //init_szAlloc(513, 1024, &_mem1024);
    }

    ~MemoryMgr()
    {

    }

public:
    static MemoryMgr& Instance()
    {//单例模式 静态
        static MemoryMgr mgr;
        return mgr;
    }
    //申请内存
    void* allocMem(size_t nSize)
    {
        
        if (nSize <= MAX_MEMORY_SZIE)
        {
            return _szAlloc[nSize]->allocMemory(nSize);
        }
        else
        {
            MemoryBlock* pReturn = (MemoryBlock*)malloc(nSize + sizeof(MemoryBlock));
            pReturn->bPool = false;
            pReturn->nID = -1;
            pReturn->nRef = 1;
            pReturn->pAlloc = nullptr;
            pReturn->pNext = nullptr;
            xPrintf("allocMem: %llx, id=%d, size=%d\n", pReturn, pReturn->nID, nSize);
            return ((char*)pReturn + sizeof(MemoryBlock));
        }

    }

    //释放内存
    void freeMem(void* pMem)
    {
        MemoryBlock* pBlock = (MemoryBlock*)((char*)pMem - sizeof(MemoryBlock));
        xPrintf("freeMem: %llx, id=%d\n", pBlock, pBlock->nID);
        if (pBlock->bPool)
        {
            pBlock->pAlloc->freeMemory(pMem);
        }
        else
        {
            if (--pBlock->nRef == 0)
                free(pBlock);
        }
    }

    //增加内存块的引用计数
    void addRef(void* pMem)
    {
        MemoryBlock* pBlock = (MemoryBlock*)((char*)pMem - sizeof(MemoryBlock));
        ++pBlock->nRef;
    }
private:
    //初始化内存池映射数组
    void init_szAlloc(int nBegin, int nEnd, MemoryAlloc* pMemA)
    {
        for (int n = nBegin; n <= nEnd; n++)
        {
            _szAlloc[n] = pMemA;
        }
    }
private:
    MemoryAlloctor<64, 1000000> _mem64;
    MemoryAlloctor<128, 1000000> _mem128;
    //MemoryAlloctor<256, 100000> _mem256;
    //MemoryAlloctor<512, 100000> _mem512;
    //MemoryAlloctor<1024, 100000> _mem1024;
    MemoryAlloc* _szAlloc[MAX_MEMORY_SZIE + 1];
    
};

#endif // !_MemoryMgr_hpp_
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间溜走了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值