(3)单线程内存池--可变大小的内存管理器

来源:互联网 发布:js阻止a标签跳转 编辑:程序博客网 时间:2024/04/30 12:38

#include <iostream>
#include <stdlib.h>
using std::cout;
using std::endl;

                         可变大小的内存空间列表

class MemoryChunk
{
public:
        MemoryChunk(MemoryChunk *nextChunk, size_t chunkSize);
        ~MemoryChunk();

        inline void *alloc(size_t size);
        inline void free(void *doomed);

        MemoryChunk *nextMemChunk() { return next; }
        size_t spaceAvailable() {return (chunkSize-bytesAlreadyAllocated); }

        enum { DEFAULT_CHUNK_SIZE = 4096 };

private:
        MemoryChunk *next;
        void *mem;

        size_t chunkSize;
        size_t bytesAlreadyAllocated;
};

MemoryChunk::MemoryChunk(MemoryChunk *nextChunk, size_t reqSize)
{
        chunkSize = reqSize > DEFAULT_CHUNK_SIZE ? reqSize :
                                DEFAULT_CHUNK_SIZE;
        next = nextChunk;
        bytesAlreadyAllocated = 0;
        mem = new char[chunkSize];
}

MemoryChunk::~MemoryChunk()
{
        delete []mem;
}

void * MemoryChunk::alloc(size_t reqSize)
{
        void *addr = static_cast<void *>(mem+bytesAlreadyAllocated);
        bytesAlreadyAllocated += reqSize;

        return addr;
}

void MemoryChunk::free(void *doomed)
{
}

//MemoryChunk 只是一个辅助类, ByteMemoryPool 类用它来实现可变大小的内存管理

class ByteMemoryPool
{
public:
        ByteMemoryPool(size_t initSize = MemoryChunk::DEFAULT_CHUNK_SIZE);
        ~ByteMemoryPool();

        inline void *alloc(size_t size);
        inline void free(void *doomed);

private:
        MemoryChunk *listOfMemoryChunks;
        void expandStorage(size_t reqSize);
};

ByteMemoryPool::ByteMemoryPool(size_t size)
{
        expandStorage(size);
}

ByteMemoryPool::~ByteMemoryPool()
{
        MemoryChunk *memChunk = listOfMemoryChunks;

        while (NULL != memChunk)
        {
                listOfMemoryChunks = memChunk->nextMemChunk();
                delete memChunk;
                memChunk = listOfMemoryChunks;
        }
}

inline void * ByteMemoryPool::alloc(size_t reqSize)
{
        size_t size = listOfMemoryChunks->spaceAvailable();
        if (size < reqSize)
                expandStorage(reqSize);

        return listOfMemoryChunks->alloc(reqSize);
}

inline void ByteMemoryPool::free(void *doomed)
{
        listOfMemoryChunks->free(doomed);
}

void ByteMemoryPool::expandStorage(size_t reqSize)
{
        listOfMemoryChunks = new MemoryChunk(listOfMemoryChunks, reqSize);
}

class Rational
{
public:
        Rational(int a = 0, int b = 1) : n(a), d(b) { }

        void *operator new(size_t size) { return memPool->alloc(size); }
        void operator delete(void *doomed) { return memPool->free(doomed); }

        static void newMemPool() { memPool = new ByteMemoryPool; }
        static void deleteMemPool() { delete memPool; }

private:
        int n;
        int d;
        static ByteMemoryPool *memPool;

};

ByteMemoryPool * Rational::memPool = NULL;

int main()
{
        Rational *arr[1000]  = { NULL };
        Rational::newMemPool();

        for (int k = 0; k < 500; ++k)
        {
                for (int i = 0; i < 1000; ++i)
                        arr[i] = new Rational(i);
                for (int j = 0; j < 1000; ++j)
                        delete arr[j];
        }

        Rational::deleteMemPool();

        return 0;
}

0 0