对象内存池实现

///
/// Copyright (c) xseekerj 2014,All Rights Reserved.
///

#ifndef _OBJECT_POOL_H_
#define _OBJECT_POOL_H_
#ifndef _POLITE_SZ_ALIGN
#define _POLITE_SZ_ALIGN
#define sz_align(d,a) (((d) + (a - 1)) & ~(a - 1))
#endif
template<typename _Ty, size_t _ElemCount = 1024>
class object_pool 
{
    typedef struct free_link_node
    { 
        free_link_node* next; 
    } *free_link;

    typedef struct chunk_link_node
    {
        char             data[sz_align(sizeof(_Ty), sizeof(void*)) * _ElemCount];
        chunk_link_node* next;
    } *chunk_link;

    object_pool(const object_pool&);
    void operator= (const object_pool&);

public:
    object_pool(void) : _Myhead(nullptr), _Mychunk(nullptr), _Mycount(0)
    {
        this->_Enlarge();
    }

    ~object_pool(void)
    {
        this->purge();
    }

    void cleanup(void)
    {
        if(this->_Mychunk = nullptr) {
            return;
        } 
        free_link_node* prev = nullptr;
        chunk_link_node* chunk = this->_Mychunk;
        for (; chunk != nullptr; chunk = chunk->next) 
        {
            char* begin     = chunk->data; 
            char* rbegin    = begin + (_ElemCount - 1) * sz_align(sizeof(_Ty), sizeof(void*)); 
            if(prev != nullptr)
                prev->next = reinterpret_cast<free_link>(begin);
            for (char* ptr = begin; ptr < rbegin; ptr += sz_align(sizeof(_Ty), sizeof(void*)) )
            { 
                reinterpret_cast<free_link_node*>(ptr)->next = reinterpret_cast<free_link_node*>(ptr + sz_align(sizeof(_Ty), sizeof(void*)));
            } 
            prev = reinterpret_cast <free_link_node*>(rbegin); 
        } 
        this->_Myhead = reinterpret_cast<free_link_node*>(this->_Mychunk->data);
        this->_Mycount = 0;
    }

    void purge(void)
    {
        chunk_link_node* ptr = this->_Mychunk;
        while (ptr != nullptr) 
        {
            chunk_link_node* deleting = ptr;
            ptr = ptr->next;
            free(deleting);
        }
        _Myhead = nullptr;
        _Mychunk = nullptr;
        _Mycount = 0;
    }

    size_t count(void) const
    {
        return _Mycount;
    }

    // if the type is not pod, you may be use placement new to call the constructor,
    // for example: _Ty* obj = new(pool.get()) _Ty(arg1,arg2,...);
    void* get(void) 
    {
        if (nullptr == this->_Myhead) 
        { 
            this->_Enlarge(); 
        }
        free_link_node* ptr = this->_Myhead;
        this->_Myhead = ptr->next;
        ++_Mycount;
        return reinterpret_cast<void*>(ptr);
    }
    void release(void* _Ptr)
    {
        ( (_Ty*)_Ptr)->~_Ty(); // call the destructor
#ifdef _DEBUG
        ::memset(_Ptr, 0x00, sizeof(_Ty));
#endif
        free_link_node* ptr = reinterpret_cast<free_link_node*>(_Ptr);
        ptr->next = this->_Myhead;
        this->_Myhead = ptr;
        --_Mycount;
    }

private:
    void _Enlarge(void)
    {
        static_assert(_ElemCount > 0, "Invalid Element Count");

        chunk_link new_chunk  = (chunk_link)malloc(sizeof(chunk_link_node)); 
#ifdef _DEBUG
        ::memset(new_chunk, 0x00, sizeof(chunk_link_node));
#endif
        new_chunk->next = this->_Mychunk; 
        this->_Mychunk  = new_chunk; 

        char* begin     = this->_Mychunk->data; 
        char* rbegin    = begin + (_ElemCount - 1) * sz_align(sizeof(_Ty), sizeof(void*)); 

        for (char* ptr = begin; ptr < rbegin; ptr += sz_align(sizeof(_Ty), sizeof(void*))) 
        { 
            reinterpret_cast<free_link_node*>(ptr)->next = reinterpret_cast<free_link_node*>(ptr + sz_align(sizeof(_Ty), sizeof(void*)));
        } 

        reinterpret_cast <free_link_node*>(rbegin)->next = nullptr; 
        this->_Myhead = reinterpret_cast<free_link_node*>(begin); 
    }

private:
    free_link     _Myhead;  // link to free head
    chunk_link    _Mychunk; // chunk link
    size_t        _Mycount; // allocated count
};

#endif









  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内存池是一种常见的内存管理技术,它可以在程序启动时预先分配一定数量的内存空间,并将其划分为多个固定大小的块,然后在程序运行过程中动态地将这些块分配给需要使用内存对象,从而减少内存碎片和内存分配的时间开销。下面是一个简单的内存池实现示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define BLOCK_SIZE 1024 #define BLOCK_NUM 10 typedef struct _memory_block { void *start; void *end; struct _memory_block *next; } memory_block; typedef struct _memory_pool { size_t block_size; memory_block *free_list; memory_block *used_list; } memory_pool; memory_pool *memory_pool_create(size_t block_size) { memory_pool *pool = (memory_pool *) malloc(sizeof(memory_pool)); pool->block_size = block_size; pool->free_list = NULL; pool->used_list = NULL; for (int i = 0; i < BLOCK_NUM; i++) { memory_block *block = (memory_block *) malloc(sizeof(memory_block)); block->start = malloc(block_size); block->end = (char *) block->start + block_size; block->next = pool->free_list; pool->free_list = block; } return pool; } void *memory_pool_alloc(memory_pool *pool, size_t size) { memory_block *block = pool->free_list; while (block) { if ((char *) block->end - (char *) block->start >= size) { void *ptr = block->start; block->start = (char *) block->start + size; if (block->start == block->end) { pool->free_list = block->next; block->next = pool->used_list; pool->used_list = block; } return ptr; } block = block->next; } return NULL; } void memory_pool_free(memory_pool *pool) { memory_block *block = pool->used_list; while (block) { memory_block *next = block->next; free(block->start); free(block); block = next; } block = pool->free_list; while (block) { memory_block *next = block->next; free(block->start); free(block); block = next; } free(pool); } int main() { memory_pool *pool = memory_pool_create(BLOCK_SIZE); char *str1 = (char *) memory_pool_alloc(pool, 10); char *str2 = (char *) memory_pool_alloc(pool, 20); char *str3 = (char *) memory_pool_alloc(pool, 30); strcpy(str1, "hello"); strcpy(str2, "world"); strcpy(str3, "memory pool"); printf("%s %s %s\n", str1, str2, str3); memory_pool_free(pool); return 0; } ``` 该示例中,首先定义了两个结构体:memory_block表示内存块,包括起始地址、结束地址和下一个内存块的指针;memory_pool表示内存池,包括块大小、空闲链表和已用链表。 然后,定义了三个函数:memory_pool_create用于创建内存池,先分配一定数量的内存块,并将其加入空闲链表;memory_pool_alloc用于从内存池中分配一块指定大小的内存空间,遍历空闲链表,找到第一个大小足够的内存块,并将其划分为新的内存空间;memory_pool_free用于释放内存池中的所有内存块,将已用链表和空闲链表中的内存块全部释放。 最后,在main函数中创建一个内存池,并使用memory_pool_alloc从内存池中分配三个字符串空间,将其赋值并打印出来,最后使用memory_pool_free释放内存池中的所有内存块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值