码迷,mamicode.com
首页 > 其他好文 > 详细

我的内存分配器

时间:2015-10-15 22:09:32      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:

ObjectPool.h

#include <stddef.h>

class ObjectPool
{
private:
    ObjectPool(unsigned int step, unsigned int size);
    ~ObjectPool();
public:
    static ObjectPool& getSingleton();
    void* alloc(size_t size);
    void dealloc(void *ptr, size_t size);
private:
    class ObjectPoolImpl;
    ObjectPoolImpl *pool;
    unsigned int size;
    unsigned int step;
};
#define USEOBJECTPOOL static void* operator new(size_t size){ return ObjectPool::getSingleton().alloc(size); }static void operator delete(void *ptr, size_t size){ ObjectPool::getSingleton().dealloc(ptr, size); }

ObjectPool.cpp

#include "ObjectPool.h"
#include "KRYMalloc.h"
#include <stdio.h>

struct ChunkData
{
    unsigned int freeNodeSize;
    ChunkData *next;
};
struct FreeNode
{
    unsigned int id;
    int flag;
    FreeNode *next;
};
static unsigned int freeNodeOffect = offsetof(FreeNode, next);
static unsigned int numNodePerChunk = 256;
class ObjectPool::ObjectPoolImpl
{
public:
    ObjectPoolImpl(){}
    void init(unsigned int size)
    {
        chunkHead = 0;
        freeHead = 0;
        freeNodeSize = freeNodeOffect + size;
        if (sizeof(FreeNode*) > size)
        {
            freeNodeSize = freeNodeOffect + sizeof(FreeNode*);
        }
        chunkDataSize = sizeof(ChunkData) + freeNodeSize * numNodePerChunk;
    }
    ~ObjectPoolImpl()
    {
        ChunkData *cur = 0;
        while (chunkHead)
        {
            cur = chunkHead;
            chunkHead = chunkHead->next;
            KRY_free(cur);
        }
    }
    void* alloc()
    {
        FreeNode *node;
        ChunkData *chunk;
        char *temp;
        if (0 == freeHead)
        {
            chunk = (ChunkData*)KRY_malloc(chunkDataSize);
            chunk->freeNodeSize = numNodePerChunk;
            chunk->next = chunkHead;
            chunkHead = chunk;
            temp = (char*)chunk + sizeof(ChunkData);

            for (unsigned int i = 0; i < numNodePerChunk; ++i)
            {
                node = (FreeNode*)temp;
                node->id = i;
                node->flag = 0;
                node->next = freeHead;
                freeHead = node;
                temp += freeNodeSize;
            }
        }
        node = freeHead;
        freeHead = freeHead->next;

        temp = (char*)node - sizeof(ChunkData) - node->id * freeNodeSize;
        chunk = (ChunkData*)temp;
        chunk->freeNodeSize -= 1;

        if (0 != node->flag)
        {
            int error = 0;
            printf("object alloc error\n");
        }
        node->flag += 1;
        return &node->next;
    }
    void dealloc(void *ptr)
    {
        char *temp = (char*)ptr - freeNodeOffect;
        FreeNode *node = (FreeNode*)temp;

        temp -= sizeof(ChunkData) + node->id * freeNodeSize;
        ChunkData *chunk = (ChunkData*)temp;
        chunk->freeNodeSize += 1;

        if (1 != node->flag)
        {
            int error = 0;
            printf("object dealloc error\n");
        }
        node->flag -= 1;
        node->next = freeHead;
        freeHead = node;
    }
private:
    ChunkData *chunkHead;
    FreeNode *freeHead;
    unsigned int freeNodeSize;
    unsigned int chunkDataSize;
};

ObjectPool::ObjectPool(unsigned int step, unsigned int size)
{
    this->step = step;
    this->size = size;
    pool = new ObjectPoolImpl[size];
    for (unsigned int i = 0; i < size; ++i)
    {
        pool[i].init(step * i + step);
    }
}
ObjectPool::~ObjectPool()
{
    delete[] pool;
}
ObjectPool& ObjectPool::getSingleton()
{
    static ObjectPool singleton(sizeof(int*), 64);
    return singleton;
}
void* ObjectPool::alloc(size_t size)
{
    //return KRY_malloc(size);
    void *data = 0;
    if (size > this->step * this->size)
    {
        data = KRY_malloc(size);
    }
    else
    {
        data = pool[(size + step - 1) / step - 1].alloc();
    }
    return data;
}
void ObjectPool::dealloc(void *ptr, size_t size)
{
    //KRY_free(ptr); return;
    if (size > this->step * this->size)
    {
        KRY_free(ptr);
    }
    else
    {
        pool[(size + step - 1) / step - 1].dealloc(ptr);
    }
}

 

我的内存分配器

标签:

原文地址:http://www.cnblogs.com/liusijian/p/4883663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!