内存泄露,内存使用情况统计

/// DbgNew.h

#ifndef DEBUGNEW_H
#define DEBUGNEW_H

#include "GameType.h"
#include "GameDefine.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <map>
#include <vector>

using namespace std;

// 内存节点
class MemNode

public:
 MemNode();
 MemNode(X_VOID* Buffer, size_t s, X_CHAR* File, X_INT Line);
 MemNode(const MemNode& Temp);

public:
 X_VOID* m_pObject;  //内存分配后获得的指针
 size_t m_nSize;  //内存分配的大小
 X_CHAR* m_szFileName; //内存分配代码所在文件位置
 X_INT m_nLineNum;  //内存分配代码所在行号
};


// 统计信息
struct Info
{
 X_UINT m_nTotalSize; //分配总大小
 X_INT m_nNewCount; //New次数
 Info()
 {
  m_nTotalSize = 0;
  m_nNewCount = 0;
 }
};

// 内存链
class NewList
{
public:
 X_BOOL IsEmpty();
 X_VOID Add(const MemNode& Temp);
 X_VOID Remove(X_VOID* Object);
 X_VOID Check();

protected:
 X_VOID __Print(string strInfo);
 
private:
 map<X_VOID*, MemNode> m_NewNodeMap; // New节点
 map<string, Info> m_StatisticsMap; // 次数等统计信息
 ofstream m_ofs;
};

// typedef
typedef map<X_VOID*, MemNode>::iterator NewNodeMapIter;
typedef map<string, Info>::iterator StatisticsMapIter;

// 重载
extern X_VOID* operator new(size_t Size, X_CHAR* FileName, X_INT LineNum);
extern X_VOID* operator new[](size_t Size, X_CHAR* FileName, X_INT LineNum);

extern X_VOID operator delete(X_VOID* Object);
extern X_VOID operator delete[](X_VOID* Object);

extern X_VOID operator delete(X_VOID* Object,  X_CHAR* FileName, X_INT LineNum);
extern X_VOID operator delete[](X_VOID* Object, X_CHAR* FileName, X_INT LineNum);

// 全局变量
extern NewList g_NewList;

#define new new(__FILE__, __LINE__)


#endif

 

/// DbgNew.cpp

#include "DbgNew.h"
#undef new
#include "XStdio.h"
#include <algorithm>
#include "TimeController.h"

MemNode::MemNode()
{
 m_pObject=0;
 m_szFileName=0;
}

MemNode::MemNode(X_VOID* Buffer, size_t s, X_CHAR* File, X_INT Line)
{
    m_pObject=Buffer;
    m_nSize=s;
    m_szFileName=File;
    m_nLineNum=Line;
}

MemNode::MemNode(const MemNode& Temp)
{
    m_szFileName=Temp.m_szFileName;
    m_nLineNum=Temp.m_nLineNum;
    m_pObject=Temp.m_pObject;
    m_nSize=Temp.m_nSize;
}

X_BOOL NewList::IsEmpty()
{
    if (m_NewNodeMap.size() > 0)
 {
  return X_FALSE;
 }
    else
 {
  return X_TRUE;
 }
}

X_VOID NewList::Add(const MemNode& Temp)
{
 m_NewNodeMap.insert(make_pair(Temp.m_pObject, Temp));
}

X_VOID NewList::Remove(X_VOID* pObject)
{
 NewNodeMapIter iter = m_NewNodeMap.begin();
 NewNodeMapIter endIter = m_NewNodeMap.end();
 iter = m_NewNodeMap.find(pObject);
 if (iter != endIter)
 {
  m_NewNodeMap.erase(iter);
 }
}

X_VOID NewList::Check()
{
    if (!IsEmpty() && TimeController::GetInstance())
    {
  X_CHAR szFileName[256]={0};
  TimeController::GetInstance()->SetThisTime();
  XStdio::Snprintf(szFileName, 256, "../log/MemCheck-%d-%d-%d-%d-%d-%d.txt",
   TimeController::GetInstance()->GetThisYear(),
   TimeController::GetInstance()->GetThisMonth(),
   TimeController::GetInstance()->GetThisDay(),
   TimeController::GetInstance()->GetThisHour(),
   TimeController::GetInstance()->GetThisMinute(),
   TimeController::GetInstance()->GetThisSecond());
  m_ofs.open(szFileName, ios_base::out);

  m_StatisticsMap.clear();
  NewNodeMapIter iter, endIter;
  StatisticsMapIter iter2, endIter2;
  iter = m_NewNodeMap.begin();
  endIter = m_NewNodeMap.end();
  X_CHAR Line[10] = {0};

  for (; iter != endIter; ++iter)
  {
   // 行号
   memset(Line, 0, sizeof(Line));
   itoa(iter->second.m_nLineNum, Line, 10);
   
   // 按文件名+行号作为KEY,统计new次数
   string key = iter->second.m_szFileName;
   key += Line;
   iter2 = m_StatisticsMap.find(key);
   if (iter2 != m_StatisticsMap.end())
   {
    iter2->second.m_nNewCount ++;
    iter2->second.m_nTotalSize += iter->second.m_nSize;
   }
   else
   {
    Info st;
    st.m_nNewCount = 1;
    st.m_nTotalSize = iter->second.m_nSize;
    m_StatisticsMap.insert(make_pair(key, st));
   }
  }

  // 从高到低统计New次数
  // sort(m_StatisticsMap.begin(), m_StatisticsMap.end());
  iter2 = m_StatisticsMap.begin();
  endIter2 = m_StatisticsMap.end();
  for (; iter2 != endIter2; iter2++)
  {
   // 文件名+行号 
   __Print(iter2->first);
   __Print("\t");
   // 调用New次数
   X_CHAR count[32];
   itoa(iter2->second.m_nNewCount, count, 10);
   __Print(count);
   __Print("\t");
   // 总大小
   X_CHAR s[64];
   itoa(iter2->second.m_nTotalSize, s, 10);
   __Print(s);
   __Print("\r\n");
  }

  m_ofs.close();
    }
}

X_VOID NewList::__Print(string strInfo)
{
 m_ofs.write(strInfo.c_str(),strInfo.length());
 m_ofs.flush();
}

NewList g_NewList;

X_VOID* operator new(size_t Size, X_CHAR* FileName, X_INT LineNum)
{
    if (Size==(size_t)0) Size=1;
    X_VOID* Result=::operator new(Size);
    if (!Result) throw bad_alloc();
    else
    {
        MemNode Temp(Result, Size, FileName, LineNum);
        g_NewList.Add(Temp);
        return Result;
    }
}

X_VOID* operator new[](size_t Size, X_CHAR* FileName, X_INT LineNum)
{
   if (Size==(size_t)0) Size=1;
   X_VOID* Result=::operator new[](Size);
   if (!Result) throw bad_alloc();
   else
   {
        MemNode Temp(Result, Size, FileName, LineNum);
        g_NewList.Add(Temp);
        return Result;
    }
}

X_VOID operator delete(X_VOID* Object)
{
 if (!Object) return;
 g_NewList.Remove(Object);
 free(Object);
}

X_VOID operator delete[](X_VOID* Object)
{
 if (!Object) return;
 g_NewList.Remove(Object);
 free(Object);
}

X_VOID operator delete(X_VOID* Object, X_CHAR* FileName, X_INT LineNum)
{
    if (!Object) return;
    g_NewList.Remove(Object);
   free(Object);
}

X_VOID operator delete[](X_VOID* Object, X_CHAR* FileName, X_INT LineNum)
{
    if (!Object) return;
    g_NewList.Remove(Object);
   free(Object);
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值