demo_memory_pool.cpp

V1.0 

#include <iostream>
#include <string>

using namespace std;

//V1.0
namespace _nmsp2
{
//#define MYMEMPOOL 1
    class A
    {
    public:
        static void *operator new(size_t size);
        static void operator delete(void *phead);
        static int m_iCout;        //分配计数统计,每new一次,就统计一次
        static int m_iMallocCount; //每malloc一次,我统计一次
    private:
        A *next;
        static A *m_FreePosi;    //总是指向一块可以分配出去的内存的首地址
        static int m_sTrunkCout; //一次分配多少倍的该类内存
    };
    int A::m_iCout = 0;
    int A::m_iMallocCount = 0;
    A *A::m_FreePosi = nullptr;
    int A::m_sTrunkCout = 5; //一次分配5倍的该类内存作为内存池子的大小

    void *A::operator new(size_t size)
    {
#ifdef MYMEMPOOL
        A *ppoint = (A *)malloc(size);
        return ppoint;
#endif
        A *tmplink;
        if (m_FreePosi == nullptr)
        {
            //为空,我要申请内存,要申请一大块内存
            size_t realsize = m_sTrunkCout * size;                  //申请m_sTrunkCout这么多倍的内存
            m_FreePosi = reinterpret_cast<A *>(new char[realsize]); //传统new,调用的系统底层的malloc
            tmplink = m_FreePosi;

            //把分配出来的这一大块内存(5小块),彼此要链起来,供后续使用
            for (; tmplink != &m_FreePosi[m_sTrunkCout - 1]; ++tmplink)
            {
                tmplink->next = tmplink + 1;
            }
            tmplink->next = nullptr;
            ++m_iMallocCount;
        }
        tmplink = m_FreePosi;
        m_FreePosi = m_FreePosi->next;
        ++m_iCout;
        return tmplink;
    }
    void A::operator delete(void *phead)
    {
#ifdef MYMEMPOOL
        free(phead);
        return;
#endif
        (static_cast<A *>(phead))->next = m_FreePosi;
        m_FreePosi = static_cast<A *>(phead);
    }

    void func()
    {
        clock_t start, end; //包含头文件 #include <ctime>
        start = clock();
        //for (int i = 0; i < 500'0000; i++)
        for (int i = 0; i < 15; i++)
        {
            A *pa = new A();
            printf("%p\n", pa);
        }
        end = clock();
        cout << "申请分配内存的次数为:" << A::m_iCout << " 实际malloc的次数为:" << A::m_iMallocCount << " 用时(毫秒): " << end - start << endl;
    }
} // namespace _nmsp2

int main()
{
    //_nmsp1::func();
    _nmsp2::func();
    return 1;
}

V2.0 

#include <iostream>
#include <string>
using namespace std;

//V2.0
//专门的内存池类   C++分配的内存的两种机制:new/delete/  内存分配器
class myallocator //必须保证应用本类的类的sizeof()不少于4字节;否则会崩溃或者报错;
{
public:
    //分配内存接口
    void *allocate(size_t size)
    {
        obj *tmplink;
        if (m_FreePosi == nullptr)
        {
            //为空,我要申请内存,要申请一大块内存
            size_t realsize = m_sTrunkCout * size; //申请m_sTrunkCout这么多倍的内存
            m_FreePosi = (obj *)malloc(realsize);
            tmplink = m_FreePosi;

            //把分配出来的这一大块内存(5小块),彼此用链起来,供后续使用
            for (int i = 0; i < m_sTrunkCout - 1; ++i) //0--3
            {
                tmplink->next = (obj *)((char *)tmplink + size);  // 
                tmplink = tmplink->next;
            } //end for
            tmplink->next = nullptr;
        } //end if
        tmplink = m_FreePosi;
        m_FreePosi = m_FreePosi->next;
        return tmplink;
    }
    //释放内存接口
    void deallocate(void *phead)
    {
        ((obj *)phead)->next = m_FreePosi;
        m_FreePosi = (obj *)phead;
    }

private:
    //写在类内的结构,这样只让其在类内使用
    struct obj
    {
        struct obj *next; //这个next就是个嵌入式指针
    };
    int m_sTrunkCout = 5; //一次分配5倍的该类内存作为内存池子的大小
    obj *m_FreePosi = nullptr;
};

//------------------------
#define DECLARE_POOL_ALLOC()                 \
public:                                      \
    static myallocator myalloc;              \
    static void *operator new(size_t size)   \
    {                                        \
        return myalloc.allocate(size);       \
    }                                        \
    static void operator delete(void *phead) \
    {                                        \
        return myalloc.deallocate(phead);    \
    }                                        \
//-----------
#define IMPLEMENT_POOL_ALLOC(classname) \
    myallocator classname::myalloc;
//---------------
class A
{
    DECLARE_POOL_ALLOC()

public:
    int m_i;
    int m_j; //为了保证sizeof(A)凑够4字节,老师演示时定义了两个int成员变量;
    int m_m;
};
IMPLEMENT_POOL_ALLOC(A)

void func()
{
    A *mypa[100];
    string a;
    for (int i = 0; i < 15; ++i)
    {
        mypa[i] = new A();
        mypa[i]->m_i = 12;
        mypa[i]->m_j = 15;

        printf("%p\n", mypa[i]);
    }
    for (int i = 0; i < 15; ++i)
    {
        delete mypa[i];
    }
}

 

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页