基于C++的内存池

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wushuangge/article/details/80825476

MemoryPool.h

#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;

template<class T>
class ObjectPool    //对象池
{
    struct BlockNode
    {
        void* _memory;    //内存块
        BlockNode* _next;   //指向下一个结点的指针。
        size_t _objNum;   //内存块对象的个数。

        BlockNode(size_t objNum)
                :_next(NULL)
                , _objNum(objNum)
        {
            _memory = malloc(objNum*_itemSize);
        }
    };
public:
    ObjectPool(size_t initNum = 32, size_t maxNum = 100000)
            :_maxNum(maxNum)
            , _useIn(0)
            , _lastDelete(NULL)
    {
        _first = _last = new BlockNode(initNum);
    }
    ~ObjectPool()
    {
        _Destory();
        _lastDelete = NULL;
        _first = NULL;
        _last = NULL;
        _maxNum = 0;
        _useIn = 0;
    }
    T* New()   //开辟内存
    {
        if (_lastDelete)   //优先使用还回来的内存对象
        {
            T* obj = _lastDelete;
            _lastDelete = *((T**)_lastDelete);   //取出_lastDelete所指对象的内容,让lastDelete指向下一块还回来的内存对象
            return new(obj)T();//定位new表达式把此对象内存初始化后返回
        }
        if (_useIn >= _last->_objNum)   //需要开辟新的内存块
        {
            size_t objNum = GetobjNum(_last->_objNum);
            _last->_next = new BlockNode(objNum);
            _last = _last->_next;
            _useIn = 0;
        }
        T* obj1 = new((T*)((char*)_last->_memory + _useIn*_itemSize))T();
        _useIn++;
        return  obj1;
    }
    static size_t InitItemSize()
    {
        if (sizeof(T) < sizeof(void*))
        {
            return sizeof(void*);
        }
        else
        {
            return sizeof(T);
        }
    }

    void Delete(T* ptr)
    {
        if (ptr)
        {
            *(T**)ptr = _lastDelete;  //把lastDelete的值放进释放的内存单元
            _lastDelete = ptr;    //再让lastDelete指向释放的内存对象。
        }

    }
protected:
    size_t GetobjNum(size_t oldNum)
    {
        size_t objNum = 2 * oldNum;
        if (objNum > _maxNum)
        {
            return _maxNum;
        }
        else
        {
            return objNum;
        }
    }
    void _Destory()
    {
        BlockNode* cur = _first;
        while (cur)
        {
            BlockNode* del = cur;
            cur = cur->_next;
            free(del->_memory);
            del->_objNum = 0;
            delete del;
        }
    }
protected:
    static size_t _itemSize;    //每个对象的大小,传进来的对象可能比一个指针小,这时需要给它一个指针的大小。
    size_t _maxNum;   //内存块的最大个数
    size_t _useIn;    //当前使用到第几个对象了
    T* _lastDelete;  //指向还回来的内存对象。
    BlockNode* _first; //链表的头结点
    BlockNode* _last;   //链表的尾结点
};

template<class T>
size_t ObjectPool<T>::_itemSize = ObjectPool<T>::InitItemSize();

test.cpp

#include <iostream>
#include "MemoryPool.h"
#include <time.h>

unsigned long GetTickCount()
{
    struct timespec ts;

    clock_gettime(CLOCK_MONOTONIC, &ts);

    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);

}

int main() {
    size_t begin, end;
    vector<int*> v;
    const size_t N = 1000000;
    v.reserve(N);
    int t;
    cout << "pool new/delete===============================" << endl;
    // 反复申请释放5次
    begin = GetTickCount();
    ObjectPool<int> pool;
    for (t = 0; t < 1; ++t)
    {
        for (size_t i = 0; i < N; ++i)
        {
            v.push_back(pool.New());
        }

        while (!v.empty())
        {
            pool.Delete(v.back());
            v.pop_back();
        }
    }

    int *p = pool.New();
    printf("p的地址:%p\n",p);

    end = GetTickCount();
    cout << "Pool:" << end - begin << endl;

    cout << "new/delete===============================" << endl;
    begin = GetTickCount();

    for (t = 0; t < 1; ++t)
    {
        for (size_t i = 0; i < N; ++i)
        {
            v.push_back(new int);
        }

        while (!v.empty())
        {
            delete v.back();
            v.pop_back();
        }
    }

    end = GetTickCount();
    cout << "new/delete:" << end - begin << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wushuangge/article/details/80825476