內存管理源代碼

 

看到我的《評C/C++實戰之內存管理》(http://www.csdn.net/develop/read_article.asp?id=11385)有8xx點的人氣,感到非常的欣慰。應網友的要求,現將源代碼貼上如下

這些代碼實現了以下功能:

1。內存分配、記錄和釋放。

2。內存分配位置,包括文件名,行號記錄。

3。內存泄漏檢測並指出導致泄漏的代碼位置,通過指出文件名,行號和分配次數(用VC的條件斷點功能然後跟蹤出去,就能查找到導致泄漏的代碼)。

4。指針錯誤使用檢測。包括指針丟失,內存越界。

5。內存使用情況。

希望大家多多對我支持,我在受到更多的鼓勵的情況下,我將更多的發表些我自己的心得和搜刮來的好的文檔,以便於大家共同進步。

歡迎來信指導:[email protected]

LDebug.h

#ifndef __LDEBUG_H_1B29CDEB_0E25_4827_A4CC_682A48197BA6
#define __LDEBUG_H_1B29CDEB_0E25_4827_A4CC_682A48197BA6

#pragma once

#ifndef ASSERT
#include <assert.h>
#define ASSERT assert
#endif

//安全刪除指針

#ifndef SAFE_DELETE
#define SAFE_DELETE(p)  {if((p)!=NULL)delete (p),(p)=NULL;}
#endif

#if _DEBUG
#pragma warning(disable : 4006 )

#if defined(new) && defined(LNEW)
#undef new
#endif

void * LLib_DebugNew(size_t nSize,const char * pFileName,int dwLine);
void LLib_DebugDelete(void * pMem,const char * pFileName,int dwLine);

inline void * _cdecl operator new (size_t nSize,const char * pFileName,int dwLine)
{
 return LLib_DebugNew(nSize,pFileName,dwLine);
}

inline void * _cdecl operator new (size_t nSize)
{
 return LLib_DebugNew(nSize,0,0);
}

inline void _cdecl operator delete (void * pMem,const char * pFileName,int dwLine)
{
 LLib_DebugDelete(pMem,pFileName,dwLine);
}

inline void _cdecl operator delete (void * pMem)
{
 LLib_DebugDelete(pMem,0,0);

#ifdef LNEW
 #define new LNEW
#else
 #define LNEW new(__FILE__,__LINE__)
#endif

#endif  //_DEBUG

#endif //__LDEBUG_H_1B29CDEB_0E25_4827_A4CC_682A48197BA6

 

LDebug.cpp

#include "stdafx.h"
#include "LDebug.h"
#include <malloc.h>

#if _DEBUG

struct LLIB_MEM_LINK
{
 DWORD  dwCC1;//效驗碼
 struct LLIB_MEM_LINK * pNext;//使分配的內存形成一個雙向鏈表
 struct LLIB_MEM_LINK * pLast;
 DWORD  dwLength;//分配的內存長度,用於後面效驗內存越界和信息統計
 const char * pName;//分配內存的文件名
 DWORD  dwLine;//分配內存的行號
 DWORD  id;//分配內存的次數
 DWORD  dwCC2;//效驗碼
};

struct LLIB_MEM_LINK   g_LLib_Mem_Head = {0xCDCDCDCD,NULL,NULL,0,NULL,0,0xCDCDCDCD};
struct LLIB_MEM_LINK * g_LLib_Mem_Current = NULL;

static int dwLLibMemObj = 0;
static int dwLLibMemUsed = 0;
static int dwLLibMemMax = 0;

static int LLib_OutputMemUsed()
{
 char buff[1024];
 if(dwLLibMemObj>0) {
  LLIB_MEM_LINK * p;
  ::sprintf(buff,"內存泄露: 有 %d 快內存導致 %d 字節內存沒有釋放/n最大內存使用: %d 字節( %d K)/n",
   dwLLibMemObj,dwLLibMemUsed,dwLLibMemMax,dwLLibMemMax/1024);
  OutputDebugString(buff);
  for(p=g_LLib_Mem_Head.pNext;p;p=p->pNext) {
   if(p->pName==NULL) {
    ::sprintf(buff,"未知位置的內存泄露: %u 字節(0x%08X)。第 %d 次分配!/n",p->dwLength,(char *)((unsigned int)p + sizeof(LLIB_MEM_LINK)),p->id);
   }
   else {
    ::sprintf(buff,"%s(%d) : 存在 %u 字節的內存泄露。第 %d 次分配!/n",p->pName,p->dwLine,p->dwLength,p->id);
   }
   OutputDebugString(buff);
  }
 }
 else {
  ::sprintf(buff,"最大內存使用: %d 字節( %d K)/n",dwLLibMemMax,dwLLibMemMax/1024);
  OutputDebugString(buff);
 }
 return 0;
}

FDIB_API void * LLib_DebugNew(size_t nSize,const char * pFileName,int dwLine)
{
 static int dwid = 0;
 struct LLIB_MEM_LINK * temp;
 if(g_LLib_Mem_Current == NULL)
 {
  _onexit(LLib_OutputMemUsed);
  g_LLib_Mem_Current = &g_LLib_Mem_Head;
 }
 dwLLibMemUsed += nSize;
 if(dwLLibMemMax < dwLLibMemUsed) dwLLibMemMax = dwLLibMemUsed;
 temp = (LLIB_MEM_LINK *)malloc(nSize + sizeof(LLIB_MEM_LINK) + sizeof(DWORD) * 2);
 if(temp != NULL)
 {
  g_LLib_Mem_Current->pNext = temp;
  temp->dwCC1 = temp->dwCC2 = 0xCDCDCDCD;
  temp->dwLength = nSize;
  temp->dwLine = dwLine;
  temp->pLast = g_LLib_Mem_Current;
  temp->pNext = NULL;
  temp->pName = pFileName;
  temp->id = dwid;
  g_LLib_Mem_Current = temp;
  DWORD * dwp = (DWORD *)(((DWORD)temp) + nSize + sizeof(LLIB_MEM_LINK));
  *dwp++ = 0xCDCDCDCD;
  *dwp = 0xCDCDCDCD;
  dwLLibMemObj++,dwid++;
  return (void *)(((DWORD)temp) + sizeof(LLIB_MEM_LINK));
 }
 else
 {
  char buff[1024];
  ::sprintf(buff,"%s(%d) : 分配不到內存(%d字節)!第 %d 次分配/n",pFileName,dwLine,nSize,dwid);
  OutputDebugString(buff);
 }
 return NULL;
}

void LLib_DebugDelete(void * pMem,const char * pFileName,int dwLine)
{
 struct LLIB_MEM_LINK * temp = (struct LLIB_MEM_LINK *)(((DWORD)pMem) - sizeof(LLIB_MEM_LINK));
 if (g_LLib_Mem_Current == temp)
 {
  g_LLib_Mem_Current = temp->pLast;
 }
 unsigned int size=_msize((void*)temp);
 if((temp->dwLength != size-sizeof(LLIB_MEM_LINK) - sizeof(DWORD) * 2) || /
  (temp->dwCC1 != 0xCDCDCDCD) || (temp->dwCC2 != 0xCDCDCDCD))
 {
  char buff[1024];
  ::sprintf("%s(%d) : 指針頭損壞。第 %d 次分配!/n",temp->pName,temp->dwLine,temp->id);
  OutputDebugString(buff);
 }
 temp->dwCC1 = temp->dwCC2 = 0xCCCCCCCC;
 DWORD * dwp = (DWORD *)(((DWORD)pMem) + temp->dwLength);
 if(*dwp != 0xCDCDCDCD || dwp[1] != 0xCDCDCDCD)
 {
  char buff[1024];
  ::sprintf("%s(%d) : 指針越界。第 %d 次分配!/n",temp->pName,temp->dwLine,temp->id);
  OutputDebugString(buff);
 }
 dwp[0] = dwp[1] = 0xCCCCCCCC;
 dwLLibMemUsed -= temp->dwLength;
 dwLLibMemObj--;
 if(temp->pNext) temp->pNext->pLast=temp->pLast;
 temp->pLast->pNext=temp->pNext;
 free((void*)temp);
}

#endif //end _DEBUG

這些代碼是我從我的一個圖象處理函數庫裏截出的,可能編譯通不過,請稍事修改。另外,可能VC總是說 operator new,operator delete重複定義,請將這段代碼編譯成一個DLL。

發佈了31 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章