記憶體管理原始碼 (轉)
看到我的《評C/C++實戰之管理》(/develop/read_article.?id=11385">http://www.csdn.net/develop/read_article.asp?id=11385)有8xx點的人氣,感到非常的欣慰。應網友的要求,現將貼上如下
這些程式碼實現了以下功能:
1。記憶體分配、記錄和釋放。
2。記憶體分配位置,包括名,行號記錄。
3。記憶體洩漏檢測並指出導致洩漏的程式碼位置,透過指出檔名,行號和分配次數(用VC的條件斷點功能然後跟蹤出去,就能查詢到導致洩漏的程式碼)。
4。指標錯誤使用檢測。包括指標丟失,記憶體越界。
5。記憶體使用情況。
希望大家多多對我支援,我在受到更多的鼓勵的情況下,我將更多的發表些我自己的心得和搜刮來的好的文件,以便於大家共同進步。
歡迎來信指導:to:lanzhengpeng@263.net">lanzhengpeng@263.net
LDe.h
#ifndef __LDEBUG_H_1B29CDEB_0E25_4827_A4CC_682A48197BA6
#define __LDEBUG_H_1B29CDEB_0E25_4827_A4CC_682A48197BA6
#pragma once
#ifndef ASSERT
#include
#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
#if _DEBUG
struct LLIB_MEM_LINK
{
D 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_ 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。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990620/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Memcached記憶體管理原始碼分析記憶體原始碼
- Flutter引擎原始碼解讀-記憶體管理篇Flutter原始碼記憶體
- Python記憶體管理機制-《原始碼解析》Python記憶體原始碼
- Paddle原始碼之記憶體管理技術原始碼記憶體
- iOS記憶體管理和malloc原始碼解讀iOS記憶體原始碼
- JAVA記憶體管理 [轉]Java記憶體
- Linux作業系統記憶體管理的原始碼實現(轉)Linux作業系統記憶體原始碼
- Windows記憶體機制解析(二)原始碼 (轉)Windows記憶體原始碼
- spark 原始碼分析之十五 -- Spark記憶體管理剖析Spark原始碼記憶體
- C++動態記憶體管理與原始碼剖析C++記憶體原始碼
- 記憶體管理 記憶體管理概述記憶體
- 記憶體管理之五 (轉)記憶體
- 記憶體管理之一 (轉)記憶體
- Windows CE記憶體管理 (轉)Windows記憶體
- Swoole 原始碼分析——記憶體模組之記憶體池原始碼記憶體
- Python原始碼閱讀-記憶體管理機制(一)Python原始碼記憶體
- Python原始碼閱讀-記憶體管理機制(二)Python原始碼記憶體
- 自動共享記憶體管理 自動記憶體管理 手工記憶體管理記憶體
- 記憶體管理篇——實體記憶體的管理記憶體
- 轉載——C++記憶體管理C++記憶體
- 改善SQL Server記憶體管理(轉)SQLServer記憶體
- spark 原始碼分析之二十二-- Task的記憶體管理Spark原始碼記憶體
- 讀Flink原始碼談設計:有效管理記憶體之道原始碼記憶體
- php原始碼02 -基本變數與記憶體管理機制PHP原始碼變數記憶體
- 【記憶體管理】記憶體佈局記憶體
- 記憶體管理記憶體
- Innodb記憶體管理解析[轉載]記憶體
- FreeBSD VM核心記憶體管理(轉)記憶體
- 段頁式記憶體管理(轉載)記憶體
- 記憶體管理兩部曲之實體記憶體管理記憶體
- Go:記憶體管理與記憶體清理Go記憶體
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- Aerospike的bin記憶體管理--即列記憶體管理ROS記憶體
- [轉帖]Solaris記憶體管理以及判定記憶體是否夠用的方法記憶體
- Linux 管理員手冊(4)--記憶體管理(轉)Linux記憶體
- 記憶體管理兩部曲之虛擬記憶體管理記憶體
- 【記憶體管理】Oracle AMM自動記憶體管理詳解記憶體Oracle
- Linux 記憶體管理:記憶體對映Linux記憶體