TOP

内存对象管理器(基于数组和链表实现)(一)
2019-09-04 00:58:14 】 浏览:58
Tags:内存 对象 管理 基于 实现

1.1 数组的特点

  • 连续的内存空间分配并且顺序存储数据,使用之前需要先分配数组个数;
  • 可以通过下标进行访问修改数据,时间复杂度为O(1);
  • 空间效率不是很好,不能随意修改数组大小;
  • 增删数据需要内存拷贝

 

1.2 链表的特点

image

  • 内存空间分配是分散的,非连续的存储数据;
  • 不能通过下标直接访问,查找的时间复杂度为O(n);
  • 增删元素,只需要改变前后指针;

1.3 基于数组和指针实现的对象管理器

image

结合了数组和链表的优点,可以O(1)查找元素,O(1)增删元素;

需要预分配内存;

 

 

2.代码实现(C++

/**
*@file ObjAllocator
*@author jasonxiong
*@date 2009-12-09
*@version 1.0
*@brief CObj对象分配类,即新版本的idxobj
*
*    (1)一般用于大型对象的内存分配
*/

#ifndef __OBJ_ALLOCATOR_HPP__
#define __OBJ_ALLOCATOR_HPP__

#include <stdio.h>

namespace ServerLib
{

typedef enum enmObjAllocType
{
    EOAT_ALLOC_BY_SELF = 0,          //!<对象内存由ObjAllocator自已动态分配
    EOAT_ALLOC_BY_SHARED_MEMORY = 1, //!<对象内存由共享内存分配
} ENMOBJALLOCTYPE;

class CObj;

typedef enum enmIdxUseFlag
{
    EIUF_FREE = 0, //!<该对象未被使用
    EIUF_USED = 1, //!<该对象已被使用
} ENMIDXUSEFLAG;

//!索引类,仅在CObjAllocator中使用,外层一般不用
class CIdx
{
public:
    CIdx();
    ~CIdx();

public:
    //!初始化函数
    int Initialize();

    //!将对象设置为未使用
    inline void SetFree()
    {
        m_iUseFlag = EIUF_FREE;
    }

    //!将对象设置为已使用
    inline void SetUsed()
    {
        m_iUseFlag = EIUF_USED;
    }

    //!判断对象是否已被使用
    inline int IsUsed() const
    {
        return m_iUseFlag == EIUF_USED;
    }

    //!获取所在链表下一个索引
    inline int GetNextIdx() const
    {
        return m_iNextIdx;
    }

    //!设置所在链表下一个索引
    inline void SetNextIdx(int iIdx)
    {
        m_iNextIdx = iIdx;
    }

    //!获取所在链表上一个索引
    inline int GetPrevIdx() const
    {
        return m_iPrevIdx;
    }

    //!设置所在链表上一个索引
    inline void SetPrevIdx(int iIdx)
    {
        m_iPrevIdx = iIdx;
    }

    //!获取指向的对象
    inline CObj *GetAttachedObj() const
    {
        return m_pAttachedObj;
    }

    //!设置指向的对象
    inline void SetAttachedObj(CObj *pObj)
    {
        m_pAttachedObj = pObj;
    }

private:
    int m_iNextIdx;       //!<对象索引块链表指针,指向后一个闲/忙索引
    int m_iPrevIdx;       //!<对象索引块链表指针,指向前一个闲/忙索引
    int m_iUseFlag;       //!<该对象是否已经被使用标志
    CObj *m_pAttachedObj; //!<所指向的对象指针
};

typedef CObj *(*Function_CreateObj)(void *);

class CObjAllocator
{
private:
    //默认构造函数,不允许上层自行调用
    CObjAllocator();

public:
    CObjAllocator(size_t uiObjSize, int iObjCount, Function_CreateObj pfCreateObj);
    ~CObjAllocator();

    /**
    *使用共享内存创建ObjAllocator
    *@param[in] pszKeyFileName 共享内存Attach的文件名
    *@param[in] ucKeyPrjID 共享内存的工程ID
    *@param[in] uiObjSize 对象大小
    *@param[in] iObjCount 对象个数
    *@param[in]
    *@return 0 success
    */
    static CObjAllocator *CreateBySharedMemory(const char *pszKeyFileName,
                                               const unsigned char ucKeyPrjID,
                                               size_t uiObjSize, int iObjCount, Function_CreateObj pfCreateObj);

    /**
    *指定内存指针来创建CObjAllocator
    *@param[in] pszMemoryAddress 指定的内存
    *@param[in] uiMemorySize 内存大小
    *@param[in] uiObjSize 对象大小
    *@param[in] iObjCount 对象个数
    *@param[in] pfCreateObj 创建CObj对象的函数,默认可以用DECLARE_DYN中的CreateObject
    *@return 0 success
    */
    static CObjAllocator *CreateByGivenMemory(char *pszMemoryAddress, size_t uiMemorySize,
                                              size_t uiObjSize, int iObjCount, Function_CreateObj pfCreateObj);

    static size_t CountSize(size_t uiObjSize, int iObjCount);

    static CObjAllocator *ResumeByGivenMemory(char *pszMemoryAddress,
                                              size_t uiMemorySize, size_t uiObjSize, int iObjCount, Function_CreateObj pfCreateObj);

public:
    //!初始化函数,将数据清空
    int Initialize();

    //!创建一个对象,成功返回对象ID,失败返回小于0的值
    int CreateObject();

    //!创建  
		
内存对象管理器(基于数组和链表实现)(一) https://www.cppentry.com/bencandy.php?fid=49&id=249973

首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇洛谷 P2725 邮票题解 下一篇洛谷 P1455 搭配购买