VC++6.0中内存泄漏检测(转)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

转自:http://blog.vckbase.com/bruceteen/archive/2004/10/28/1130.aspx

这篇文章是对2004-09-02日发表的《VC++6.0中简单的内存泄漏检测事例代码》(已经删除)的更新.

对C++代码而言,内存泄漏问题虽然有诸多方法避免,但实际代码编写的时候,或出于自信或出于复杂性的考虑,常常还会用到原始的operator new,这不可避免的会带来内存泄漏的可能,不久前本人因为违反了"可用于被多态继承的基类其析构函数应当有virtual修饰"的法则( 一不小心就忘了写virtual ^_^ ),导致了内存泄漏,因此我觉得出于安全考虑,在代码中加入内存泄漏检查机制还是很必要的,也因为这次的内存泄漏事件促使我写出这一篇文章.

VC++中本身就有内存泄漏检查的机制,你可以在向导生成的支持MFC的工程中看到如下代码:
  #ifdef _DEBUG
  #define new DEBUG_NEW
  #undef THIS_FILE
  static char THIS_FILE[] = __FILE__;
  #endif
通过它们,你能非常容易的发现代码中的内存泄漏,但是如果手工将这个功能移植到非MFC工程中去是很繁琐的一件事,另外它还有一个bug,在多线程并发调用这个DEBUG_NEW时会导致系统级错误,因此本人在此重写了这个功能,将以下的debug_new.h和debug_new.cpp添加到工程中,并在需要检测的cpp中#include "debug_new.h"和main中一开始处加入REG_DEBUG_NEW宏即可.

1. debug_new.h 源代码

/************************************************************************/
/* comment:  此文件与debug_new.cpp配合使用,用于在调试期发现内存泄漏     */
/*           仅在VC++编译器中适用(包括Intel C++,因为它使用了相同的库)   */
/* 作者:     周星星 http://blog.vckbase.com/bruceteen/                  */
/* 版权申明: 无,可任意 使用,修改 和 发布                                */
/************************************************************************/

/* sample

#include <iostream>
#include "debug_new.h" // +
using namespace std;

int main( void )
{
    REG_DEBUG_NEW; // +

    char* p = new char[2];

    cout << "--End--" << endl;
    return 0;
}

在VC++ IDE中按F5调试运行将会在Output窗口的Debug页看到类似如下的提示:
Dumping objects ->
d:/test.cpp(10) : {45} normal block at 0x003410C8, 2 bytes long.
Data: <  > CD CD
Object dump complete.

如果不出现如上提示请Rebuild All一次.

*/


#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_

    #ifdef _DEBUG

        #undef new
        extern void _RegDebugNew( void );
        extern void* __cdecl operator new( size_t, const char*, int );
        extern void __cdecl operator delete( void*, const char*, int);
        #define new new(__FILE__, __LINE__)
        
        #define REG_DEBUG_NEW _RegDebugNew();

    #else

        #define REG_DEBUG_NEW

    #endif
// _DEBUG

#endif
// _DEBUG_NEW_H_


2. debug_new.cpp 源代码
/************************************************************************/
/* comment:  此文件与debug_new.h配合使用,用于在调试期发现内存泄漏       */
/*           仅在VC++编译器中适用(包括Intel C++,因为它使用了相同的库)   */
/* 作者:     周星星 http://blog.vckbase.com/bruceteen/                  */
/* 版权申明: 无,可任意 使用,修改 和 发布                                */
/************************************************************************/

//#include "debug_new.h"

#ifdef _DEBUG

#include <windows.h>
#include <crtdbg.h>

class _CriSec
{
    CRITICAL_SECTION criSection;
public:
    _CriSec()    { InitializeCriticalSection( &criSection ); }
    ~_CriSec()   { DeleteCriticalSection( &criSection );     }
    void Enter() { EnterCriticalSection( &criSection );      }
    void Leave() { LeaveCriticalSection( &criSection );      }
} _cs;

void _RegDebugNew( void )
{
    _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );
}
void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine )
{
    // comment 1: MFC中提供的debug new虽然加了锁,但我在实际测试的时候发现多线程并发
    //            调用的时候还是抛出了系统错误,所以我在这里加了一个线程互斥量.
    // comment 2: debug new和debug delete之间需不需要互斥我并不知道,保险起见,我同样
    //            加了线程互斥量.
    // comment 3: 按照C++标准规定,在operator new失败后应当调用set_new_handler设置的
    //            函数,但是MSDN中却说"头文件new中的set_new_handler是stub的,而应该使
    //            用头文件new.h中的_set_new_handler",这简直是滑天下之大稽.
    //            以下是VC++6.0中的set_new_handler定义:
    //                new_handler __cdecl set_new_handler( new_handler new_p )
    //                {
    //                    assert( new_p == 0 ); // cannot use stub to register a new handler
    //                    _set_new_handler( 0 );
    //                    return 0;
    //                }
    //            所以我也无计可施,只能舍弃set_new_handler的作用.

    _cs.Enter();
    void* p = _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );
    _cs.Leave();
    return p;
}
void __cdecl operator delete( void* p, const char* /*lpszFileName*/, int /*nLine*/ )
{
    _cs.Enter();
    _free_dbg( p, _CLIENT_BLOCK );
    _cs.Leave();
}

#endif


3. 事例代码
#include <iostream>
#include "debug_new.h"
using namespace std;

int main( void )
{
    REG_DEBUG_NEW;

    char* p = new char[2];
    p[0] = 'A';
    p[1] = 'B';

    cout << "--End--" << endl;
    return 0;
}


4. 结果输出
在VC++ IDE中按F5调试运行将会在Output窗口的Debug页看到类似如下的提示:
……
Dumping objects ->
d:/test.cpp(10) : {45} normal block at 0x003410C8, 2 bytes long.
Data: <AB> 41 42
Object dump complete.
……
 

VC++内存泄漏检测工具实战指南 C++开发实践中,尤其是在使用Visual C++VC++)构建Windows平台应用程序时,内存管理的复杂性使得内存泄漏成为长期困扰开发者的关键问题。尽管现代C++标准已引入智能指针、RAII等机制来缓解手动内存管理的风险,但在遗留代码、大型系统集成或性能敏感场景中,原始newdelete操作仍广泛存在。因此,依赖高效的内存泄漏检测工具进行辅助分析,已成为保障软件质量不可或缺的一环。 阅读详情

相关推荐

vc++内存泄漏检测工具

一款很好用 的内存泄漏检测工具,对初学者是个很好的学习机会

VC检测内存泄露

头文件中加入如下代码 #define _CRTDBG_MAP_ALLOC #include #include #ifdef _DEBUG #ifndef DBG_NEW #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) #define new DBG_NEW #endif #endif main函数中加入如下代码

yjz1409276的专栏 894

VC6 内存泄漏检测

利用VC++6.0撰写内存泄漏检测的方法

vc++ 2005 内存泄漏检测

当有内存泄漏的时候,一般都会在输出中打印源文件名称及行号,如果是下面这种情况时, Detected memory leaks! Dumping objects -> {67} normal block at 0x00780E80, 64 bytes long. Data: CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dum

suisuibianbian的专栏 1185

VC++ 内存泄漏检测(调试篇)

在项目的InitInstance入口函数里面添加如下代码 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//_CrtDumpMemoryLeaks(); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); _CrtSetBreakAlloc(248...

老狼的专栏 567

VC++内存泄漏检测与定位

VC++内存泄漏检测与定位 发原文地址:http://blog.sina.com.cn/s/blog_45eaa01a0102uy4i.html 本文大部分内容来自网络,只是做了适当的修改和补充,以便更贴近实际应用。 一 对于MFC程序 如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏。例如: class CMyApp : public CWinApp { public: BOOL InitApplication() { int* leak = new...

bmjhappy的专栏 555

VC++6.0内存泄漏检测

  VC++6.0内存泄漏检测 摘自:VC知识库BLOG-周星星 网址:blog.vckbase.com/bruceteen/对C++代码而言,内存泄漏问题虽然有诸多方法避免,但实际代码编写的时候,或出于自信或出于复杂性的考虑,常常还会用到原始的operator new,这不可避免的会带来内存泄漏的可能,不久前本人因为违反了"可用于被多态继承的基类其析构函数应当有virtual修

wbczyh的专栏 2026

VC++6.0内存泄漏检测

最近看了周星星 Blog 中的一篇文章:“VC++6.0内存泄漏检测”,受益匪浅,便运行其例子代码想看看 Output 窗口中的输出结果,可惜怎么弄其输出都不是预期的东西,郁闷了半天,便到水坛里找到周星星,请求他指点一、二,然而未果。没有办法,最后我一头栽进 MSDN 库狂搜了一把,功夫不负有心人,我搜出很多有关这方面的资料,没过多久我便基本上就找到了答案...... 首先,检测内存泄漏

记得评论哦 2203

VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏

VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏作者:JerryZ下载例子源代码  最近看了周星星 Blog 中的一篇文章:“VC++6.0内存泄漏检测”,受益匪浅,便运行其例子代码想看看 Output 窗口中的输出结果,可惜怎么弄其输出都不是预期的东西,郁闷了半天,便到水坛里找到周星星,请求他指点一、二,然而未果。没有办法,最后我一头栽进 MSDN 库狂搜了一把,功夫不负有心人

bairny的专栏 1万+

VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏[]

/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:“最大的长处也可能成为最大的弱点”,那么 C/C++ 应用程序正好印证了这句话。在 C/C++ 应用程序开发过程中,动态分配的内存处理不当是最常见的问题。其中,最难捉摸也最难检测的错误之一就是内存泄漏,即未能正确释放以前分配的内存的错误。偶尔发生的少量内存泄漏可能不会引起我们的注意,但泄漏大量内存的程序或泄漏日...

weixin_30510153的博客 82

VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏

<br />自:http://tech.ddvip.com/2007-03/117413967621578.html

304

VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏 调试方法

VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏 作者:JerryZ 下载例子源代码   最近看了周星星 Blog 中的一篇文章:“VC++6.0内存泄漏检测”,受益匪浅,便运行其例子代码想看看 Output 窗口中的输出结果,可惜怎么弄其输出都不是预期的东西,郁闷了半天,便到水坛里找到周星星,请求他指点一、二,然而未果。没有办法,最后我一头栽进 MSDN 库狂搜了

yxnyxnyxnyxnyxn的专栏 2892

vc++内存泄漏检测

vc++内存泄漏检测

huangyimin的专栏 1385

如何在VC++ 6.0中启用内存泄漏检测

VC++ IDE 的默认状态是没有启用内存泄漏检测机制的,也就是说即使某段代码有内存泄漏,调试会话的 Output 窗口的 Debug 页不会输出有关内存泄漏信息。你必须设定两个最基本的机关来启用内存泄漏检测机制。  一是使用调试堆函数:  #define _CRTDBG_MAP_ALLOC  #include   #include   注意:#include 语句的顺序。如果更改此顺序,所使用的

冷秋魂的专栏 1171

VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏

导读:  最近看了周星星 Blog 中的一篇文章:“VC++6.0内存泄漏检测”,受益匪浅,便运行其例子代码想看看 Output 窗口中的输出结果,可惜怎么弄其输出都不是预期的东西,郁闷了半天,便到水坛里找到周星星,请求他指点一、二,然而未果。没有办法,最后我一头栽进 MSDN 库狂搜了一把,功夫不负有心人,我搜出很多有关这方面的资料,没过多久我便基本上就找到了答案...... 

wuyinling1984的专栏 619
上一篇: 共享软件业余者VS共享软件专业者(转)
下一篇: VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏(转)
bairny
博客等级 码龄23年 12粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值