C++内存管理

#ifndef _EXCELSIOR_CACHEMANAGE_H_
#define _EXCELSIOR_CACHEMANAGE_H_
#include <string>
using namespace std;
#include "List.h"

struct TCacheAllocStauts 
{
    UINT8** pType;
    UINT32 start;
    UINT32 size;
};

class CacheManage
{
protected:
    CacheManage(const CacheManage&){}
public:
    /**********************************************************************
    * 功 能 : // 构造函数
    * 输入参数: // size:初始化分配的内存大小,默认4M
    * 输出参数: // 
    * 返 回 值: // 
    ***********************************************************************/
    CacheManage(UINT32 size = 4 * 1024 * 1024){}
    ~CacheManage()
    {}

    /**********************************************************************
    * 功 能 : // 分配一块内存给pType
    * 输入参数: // pType:要申请内存的对象地址,size:要分配的内存大小
    * 输出参数: // pType:分配成功不为NULL,否则为NULL
    * 返 回 值: // 分配结果,失败返回NULL
    ***********************************************************************/
    UINT8* Alloc(UINT8* &pType, UINT32 size);

    /**********************************************************************
    * 功 能 : // 收回分配给pType的内存,调用该方法前,需要做相应的清理工作
    * 输入参数: // pType:把内存分配给的对象地址
    * 输出参数: // 
    * 返 回 值: // 
    ***********************************************************************/
    void Free(UINT8* &pType);

    /**********************************************************************
    * 功 能 : // 打印缓存信息
    * 输入参数: // 
    * 输出参数: // 
    * 返 回 值: // 缓存信息
    ***********************************************************************/
    string ToString();
private:
    /**********************************************************************
    * 功 能 : // 整理零碎内存
    * 输入参数: // 
    * 输出参数: // 
    * 返 回 值: // 
    ***********************************************************************/
    void CollectFreeMemory();
    UINT8 *m_pCache;    /* 保存一块用来分配的连续内存区域 */
    UINT32 m_iPos;
    UINT32 m_size;
    CNodeList<TCacheAllocStauts> m_stautsList; /* 保存已经分配的状态 */
};
#endif
//程序的实现:

/********************************************************************
    Copyright (C) 2007 - All Rights Reserved
创建时间: 2007/11/27 10:41
文件名 : CacheManage.cpp
作者:   Fu.Changyou
    版本:       V1.0 
目的:       缓存管理类的实现
    函数列表:   
    修改日志: 
        <作者> <时间>   <版本>   <描述>
*********************************************************************/

#include "CacheManage.h"
#include "Exception.h"

/**********************************************************************
* 功 能 : // 构造函数
* 输入参数: // size:初始化分配的内存大小
* 输出参数: // 
* 返 回 值: // 
***********************************************************************/
CacheManage::CacheManage(UINT32 size /* = 4 * 1024 * 1024 */)
{
    if (size <= 0)
    {
        throw CException("alloc size[%u] error", size);
    }

    NEW(m_pCache, UINT8[size]);

    if (NULL == m_pCache)
    {
        throw CException("alloc memory error, memory size is %u", size);
    }

    m_iPos = 0;
    m_size = size;
}

CacheManage::~CacheManage()
{
    DELETEPTR(m_pCache);
}

/**********************************************************************
* 功 能 : // 分配一块内存给pType
* 输入参数: // pType:要申请内存的对象地址,size:要分配的内存大小
* 输出参数: // pType:分配成功不为NULL,否则为NULL
* 返 回 值: // 分配结果,失败返回NULL
***********************************************************************/
UINT8* CacheManage::Alloc(UINT8* &pType, UINT32 size)
{
    /* 申请的大小不能小于等于0 */
    if (size <= 0)
    {
        return NULL;
    }

    /* 如果内存不够分配,就需要整理零碎内存 */
    if (size > m_size - m_iPos)
    {
        CollectFreeMemory();

        /* 如果整理后还是不够的话,就申请失败 */
        if (size > m_size - m_iPos)
        {
            return NULL;
        }
    }

    pType = m_pCache + m_iPos;
    /* 保存该信息 */
    TCacheAllocStauts stauts;
    stauts.pType = &pType;
    stauts.start = m_iPos;
    stauts.size = size;
    m_stautsList.AddTail(stauts);

    /* 改变当前位置,以备下次别的模块申请 */
    m_iPos += size;

    /* 分配内存 */
    return pType;
}

/**********************************************************************
* 功 能 : // 收回分配给pType的内存,调用该方法前,需要做相应的清理工作
* 输入参数: // pType:把内存分配给的对象的地址
* 输出参数: // 
* 返 回 值: // 
***********************************************************************/
void CacheManage::Free(UINT8* &pType)
{
    TNode<TCacheAllocStauts> *pNode = m_stautsList.Front();
    
    while (pNode)
    {
        if (pNode->Value().pType == &pType)
        {
            int iStart = pNode->Value().start;
            int iSize = pNode->Value().size;
            /* 从状态信息链表中删除该信息 */
            m_stautsList.Remove(pNode);
            /* 将该内存置为0 */
            memset(m_pCache + iStart, 0, iSize);
            break;
        }
        pNode = m_stautsList.Next();
    }
}

/**********************************************************************
* 功 能 : // 打印缓存信息
* 输入参数: // 
* 输出参数: // 
* 返 回 值: // 缓存信息
***********************************************************************/
string CacheManage::ToString()
{
    /* head */
    string sTmp = "Cache Informations is:\n"
        "Size:";
    sTmp += m_size;
    sTmp += "\nCurrent Position:";
    sTmp += m_iPos;

    /* body */
    char* pSpace1 = " ";
    char* pSpace2 = " ; ";
    int iPos = 0;
    char sTmp1[64];
    char sTmp2[32];
    memset(sTmp1, 0, sizeof(sTmp1));
    memset(sTmp2, 0, sizeof(sTmp2));

    while (iPos < m_size)
    {
        if ((iPos % 16) == 0)
        {
            if (sTmp1[0] != 0)
            {
                sTmp += "\n";
                sTmp += sTmp1;
                sTmp += sTmp2;
            }
            memset(sTmp1, 0, sizeof(sTmp1));
            memset(sTmp2, 0, sizeof(sTmp2));
            sprintf(sTmp2, "%s", pSpace2);
        }
        if (m_pCache[iPos] < 0x10)
        {
            sprintf(sTmp1, "%s0%X%s", sTmp1, m_pCache[iPos], pSpace1);
            sprintf(sTmp2, "%s.", sTmp2);
        }
        else
        {
            sprintf(sTmp1, "%s%2X%s", sTmp1, m_pCache[iPos], pSpace1);
            sprintf(sTmp2, "%s%c", sTmp2, m_pCache[iPos]);
        }
        iPos++;
    }
    int iTmp = strlen(sTmp1);
    while (iTmp < 48)
    {
        sprintf(sTmp1, "%s ", sTmp1);
        iTmp++;
    }
    sTmp += "\n";
    sTmp += sTmp1;
    sTmp += sTmp2;

    return sTmp;
}

/**********************************************************************
* 功 能 : // 整理零碎内存,整理完后得到的是一片连续的内存区域
* 输入参数: // 
* 输出参数: // 
* 返 回 值: // 
***********************************************************************/
void CacheManage::CollectFreeMemory()
{
    UINT32 iPos = 0;
    TNode<TCacheAllocStauts> *pNode = m_stautsList.Front();
    while (pNode)
    {
        /* 数据移位,填充左边的空格(低位的空余内存) */
        if (pNode->PTR_Value()->start > iPos)
        {
            memcpy(m_pCache+iPos, m_pCache + pNode->PTR_Value()->start, pNode->PTR_Value()->size);
            *(pNode->PTR_Value()->pType) = m_pCache + iPos;
        }
        /* 将当前位置移动size大小,并检查下一个分配的内存 */
        iPos += pNode->PTR_Value()->size;
        pNode = m_stautsList.Next();
    }

    /* 将剩余的内存置0,并重置可分配内存的起始位置 */
    memset(m_pCache + iPos, 0, m_size - iPos);
    m_iPos = iPos;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值