内存管理源代码

原创 2001年12月06日 09:19:00

 

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

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

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

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

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

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

5。内存使用情况。

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

欢迎来信指导: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 <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。

内存管理(Linux内核源码分析)

背景本篇博客试图通过linux内核源码分析linux的内存管理机制,并且对比内核提供的几个分配内存的接口函数。然后聊下slab层的用法以及接口函数。内核分配内存与用户态分配内存内核分配内存与用户态分配...
  • hty46565
  • hty46565
  • 2017年07月12日 10:03
  • 528

linux内存管理源码分析 - 概述

linux内存管理源码分析 - 概述 本文为原创,转载请注明:http://www.cnblogs.com/tolimit/  http://www.cnblogs.com/tolimit/p...
  • zdy0_2004
  • zdy0_2004
  • 2015年06月05日 22:18
  • 595

Linux内存管理浅析(一)

1.Linux内存管理的主要内容 a.      虚拟内存管理 b.      内核空间内存管理 c.      用户空间内存管理 2.虚拟内存和物理内存映射 ZONE_HIGH...
  • u012398362
  • u012398362
  • 2016年11月27日 19:40
  • 966

xv6源码分析(四):内存管理

xv6通过页表机制实现了对内存空间的控制。页表使得 xv6 能够让不同进程各自的地址空间映射到相同的物理内存上,还能够为不同进程的内存提供保护。 除此之外,我们还能够通过使用页表来间接地实现一些特殊功...
  • qq_25426415
  • qq_25426415
  • 2017年01月21日 15:15
  • 1841

Ruby的内存管理机制。

原文在此 http://www.theirishpenguin.com/2009/10/29/understanding-how-ruby-stores-objects-in-memory-the-r...
  • ChenShaoXunHuan
  • ChenShaoXunHuan
  • 2015年03月03日 11:20
  • 1332

Lua内存管理

Lua  要求用户给出一个内存管理函数,在 Lua创建虚拟机的时候传入。。  它利用 C 标准库中的函数实现了一个默认的内存管理器,这也可以帮助我们理解这个内存管理...
  • liutianshx2012
  • liutianshx2012
  • 2015年01月19日 17:00
  • 1348

C/C++内存管理之内存池

C++内存管理一直是我比较困惑的问题。俗话说初生牛犊不怕虎,做点啥都new一个,然后delete一个。根本不知道底层会有怎么样的运行机制,慢慢地学习才知道以前学习中有一些东西是不可能在工业中应用的。所...
  • bateerBATEER
  • bateerBATEER
  • 2017年03月28日 21:38
  • 310

SylixOS 经得起检验的国产操作系统 (三)

本篇文章将介绍SylixOS软件框架以及POSIX标准。SylixOS官网:http://www.sylixos.com。...
  • sun_junhui
  • sun_junhui
  • 2015年07月08日 16:12
  • 2066

深入浅出Linux内核内存管理基础

1 背景知识 1.1 用户空间与内核空间内存的划分        从Linux操作系统层次上,内存可划分为用户空间内存和内核空间内存。        32位的CPU,最大寻址范围为2^32 - 1也就...
  • acs713
  • acs713
  • 2015年01月18日 16:45
  • 4176

Linux内存管理详解

前一段时间看了《深入理解Linux内核》对其中的内存管理部分花了不少时间,但是还是有很多问题不是很清楚,最近又花了一些时间复习了一下,在这里记录下自己的理解和对Linux中内存管理的一些看法和认识。 ...
  • u010229420
  • u010229420
  • 2016年09月19日 21:29
  • 623
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存管理源代码
举报原因:
原因补充:

(最多只允许输入30个字)