内存池结合嵌入式指针

代码示例

MyAlloc 是一个采用嵌入式指针做的内存池分配内存的类,采用这种技术的类,其sizeof()的值不少于4。

class MyAlloc 
{
public:
    void* allocate(size_t size);  // size分配的内存大小
    void deallocate(void* pa);
private:
    struct Obj
    {
        struct Obj* pNext;
    };
    Obj* m_FreePos = nullptr;  // 总是指向一块可以分配出去的内存的首地址
    int m_sTrunkCount = 5;  // 一次分配多少倍的该类内存
};

void* MyAlloc::allocate(size_t size)  // 这个size是系统根据类的大小指定的
{
    //A* pa = (A*)malloc(size);
    //return pa;
    Obj* pTemp;
    if (m_FreePos == nullptr)
    {
        // 为空,我需要申请一大块内存
        size_t realsize = m_sTrunkCount * size;
        m_FreePos = reinterpret_cast<Obj*>(malloc(realsize));  // reinterpret_cast 无条件转
        // 此处的new是传统的new(不是我们自己定义的new)该出调用的是底层的malloc
        pTemp = m_FreePos;

        // 把分配的这一大块内存(5小块)彼此之间链接起来,供后续使用
        for (int i = 0; i < m_sTrunkCount - 1; ++i)
        {
            pTemp->pNext = (Obj*)((char*)pTemp + size);  
            // 先转成char* 加上一个A类的size,就转到下一个A类的地方
            pTemp = pTemp->pNext;
        }
        pTemp->pNext = nullptr;  // 最后一个
    }
    pTemp = m_FreePos;
    m_FreePos = m_FreePos->pNext;
    return pTemp;
    // new第二块新内存的时候,第一块内存的最后一个元素,还是指向第二块内存的起始地址m_FreePos
    // 这个关系式在new第一块内存的时候建立的链接关系
}
void MyAlloc::deallocate(void* pa)
{
    (static_cast<Obj*>(pa))->pNext = m_FreePos;  
    m_FreePos = static_cast<Obj*>(pa);
    // 将释放的任意一块内存,加入空闲的内存块中
}

class A  // 使用MyAlloc的类的sizeof要不少于4字节
{
public:
    int m_i;
    int m_j;

public:
    static MyAlloc m_alloc;
    static void* operator new(size_t size)
    {
        return m_alloc.allocate(size);
    }

    static void operator delete(void* pa)
    {
        return m_alloc.deallocate(pa);
    }

};

MyAlloc A::m_alloc;

 

posted @ 2020-07-02 22:27  min_zhi  阅读(156)  评论(0编辑  收藏