内存管理源代码 (转)

内存管理源代码 (转)[@more@]

 

看到我的《评C/C++实战之内存管理》(.NET/develop/read_article.ASP?id=11385">http://www.csdn.net/develop/read_article.asp?id=11385)有8xx点的人气,感到非常的欣慰。应网友的要求,现将源代码贴上如下

这些代码实现了以下功能:

1。内存分配、记录和释放。

2。内存分配位置,包括文件名,行号记录。

3。内存泄漏检测并指出导致泄漏的代码位置,通过指出文件名,行号和分配次数(用VC的条件断点功能然后跟踪出去,就能查找到导致泄漏的代码)。

4。指针错误使用检测。包括指针丢失,内存越界。

5。内存使用情况。

希望大家多多对我支持,我在受到更多的鼓励的情况下,我将更多的发表些我自己的心得和搜刮来的好的文档,以便于大家共同进步。

欢迎来信指导:Mailto:lanzhengpeng@263.net" rel="nofollow">lanzhengpeng@263.net

LDebug.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
{
 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 字节内存没有释放 最大内存使用: %d 字节( %d K) ",
 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 次分配! ",p->dwLength,(char *)((unsigned int)p + sizeof(LLIB_MEM_LINK)),p->id);
 }
 else {
 ::sprintf(buff,"%s(%d) : 存在 %u 字节的内存泄露。第 %d 次分配! ",p->pName,p->dwLine,p->dwLength,p->id);
 }
 OutputDebugString(buff);
 }
 }
 else {
 ::sprintf(buff,"最大内存使用: %d 字节( %d K) ",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 次分配 ",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 次分配! ",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 次分配! ",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/10796304/viewspace-951968/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10796304/viewspace-951968/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值