内存泄漏问题

  • Post author:
  • Post category:其他



这篇文章是对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.

……

posted on 2004-10-28 04:49 周星星 阅读(39808)



评论(34)






编辑






收藏




评论





#





好帖!
2004-10-28 05:01



一笑


收藏ing…





#





re: VC++6.0中内存泄漏检测
2004-10-30 01:26

lxwde
我也支持一下楼主





#





re: VC++6.0中内存泄漏检测
2004-11-01 10:28

zhuyie
默认显示的字体好像太小了,呵呵;





#





to zhuyie:
2004-11-01 21:40



周星星


不知道为什么字体和大小这几天变了,而且不受我控制,以前还好好的。





#





re: VC++6.0中内存泄漏检测
2004-11-03 09:39



soloist


对”头文件new中的set_new_handler是stub的”这句话中”stub”的意思我有点不太明白,是不是指set_new_handler本身并没有实现任何功能,只是提供了一个接口,真正功能的完成靠的是在内部调用_set_new_handler?

另外,在实际开发的时候_CrtSetDbgFlag这个函数应该越早调用越好,因为C++中全局对象的初始化是在main函数之前,而在它们的构造函数里极有可能做了分配堆内存的动作,如果我们仅仅在刚进入main的时候调用_CrtSetDbgFlag,则无法检测到有可能由上述全局对象引起的内存泄漏。我的建议是定义一个类,在它的构造函数里调用_CrtSetDbgFlag,然后在main函数所在的CPP里首先定义一个上述类的全局对象。当然,C++标准不保证全局变量初始化的顺序,所以先于它的全局变量初始化引发的堆内存分配仍然不受监控,但是这个方法毕竟能扩大一点监控范围,对吧?

一个问题和一个建议,还请周星星兄指正。





#





to soloist:
2004-11-03 22:03



周星星


VC++6.0中的set_new_handler:

/***

* WARNING: set_new_handler is a stub function that is provided to

* allow compilation of the Standard Template Library (STL).

* Do NOT use it to register a new handler. Use _set_new_handler instead.

* However, it can be called to remove the current handler:

* set_new_handler(NULL); // calls _set_new_handler(NULL)

*******************************/

new_handler __cdecl set_new_handler (new_handler new_p)

{

// cannot use stub to register a new handler

assert(new_p == 0);

// remove current handler

_set_new_handler(0);

return 0;

}

对于第二点非常感谢,我当初甚至想使用

#pragma comment(linker, “/ENTRY:Inti”)

void __cdecl Init( void )

{

……

}

来让它一开始就起作用,但……^_^,不会,免得用法弄错了,遗笑大方,要不你帮我改改?:)





#





re: 周星星
2004-11-04 10:48



soloist


用#pragma comment(linker, “/ENTRY:Init”),我也试了一下。如果在Init中做完了指定的动作后直接调用main或者WinMain的话我觉得不太安全,因为通过观察代码发现在诸如mainCRTStartup这样的默认入口函数中系统做了许多检查和初始化的工作(好象挺复杂,我也没看懂)。但是如果要显式地调用它又得导入不少VC的内部文件(而且我也没试成功,如果你能成功调用的话,烦请告诉方法与具体设置),将来用新的开发工具会否出问题就未可知了。

我觉得我上次提的建议也不很好,还不如直接在你的operator new的入口处加上对_CrtSetDbgFlag的调用,反正它也几乎不耗什么时间。这样不管任何地方用到new都能保证DbgFlag标志已经正确设置了。呵呵,我实在想不到其它的更好方法了^_^。

另外还建议(为什么我的话这么多?)将你的_CriSec _cs全局对象定义改成:

_CriSec& _cs()

{

static _CriSec s_cs;

return s_cs;

};

而所有用到_cs的地方改成_cs()。因为全局对象初始化顺序不能确定,所以有可能当其它全局变量在初始化中调用new时_cs本身还没有被初始化。用这种函数的形式可以保证任何时候通过_cs()得到的是一个被正确初始化的_CriSec对象的引用。





#





to soloist:
2004-11-04 21:51



周星星


谢谢你的热心指正,两个观点都非常正确,我有空就改掉它。





#





很困惑,希望得到指点一下
2004-11-09 07:47

笑柄
1.新建win32 console application 取名字test

2.new file ->c++ header debug_new.h,copy…;

3.new file ->c++ source debug_new.cpp,copy…;

4.new file ->c++ source test.cpp,copy…;

5.rebuild all

6.f5

出来下面这个,我是VC6.0+win2003s,好象都没打补丁

Loaded ‘ntdll.dll’, no matching symbolic information found.

Loaded ‘C:/WINDOWS/system32/kernel32.dll’, no matching symbolic information found.

The thread 0x784 has exited with code 0 (0x0).

The program ‘E:/MYPROJECT/test/Debug/test.exe’ has exited with code 0 (0x0).





#





to 笑柄:
2004-11-09 21:39



周星星


我没有win2003s,等我有了,我测试一下。谢谢你告诉我这个错误!





#





VC 6.0中内存泄漏检测[TrackBack]
2004-11-09 09:05



NetSniffer


Ping Back来自:blog.csdn.net

NetSniffer引用了该文章,地址:



http://blog.csdn.net/netsniffer/archive/2004/11/09/173437.aspx








#





re: VC++6.0中内存泄漏检测
2004-11-19 05:43



kevie221@hotmail.com


我跟笑柄得到差不多的结果,我是2000+vc6.0,结果如下:

Loaded ‘C:/WINNT/system32/ntdll.dll’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/KERNEL32.DLL’, no matching symbolic information found.

Loaded ‘C:/Program Files/rising/rav/ApiHook.dll’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/ADVAPI32.DLL’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/rpcrt4.dll’, no matching symbolic information found.

Loaded ‘C:/Program Files/rising/rav/Memmon.dll’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/USER32.DLL’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/GDI32.DLL’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/imm32.dll’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/lpk.dll’, no matching symbolic information found.

Loaded ‘C:/WINNT/system32/usp10.dll’, no matching symbolic information found.

The thread 0x248 has exited with code 0 (0x0).

The thread 0x4D0 has exited with code 0 (0x0).

The program ‘C:/PROGRAM FILES/MICROSOFT VISUAL STUDIO/MYPROJECTS/debug_new/Debug/debug_new.exe’ has exited with code 0 (0x0).

请问期望的结果为什么没有出现?盼望答复





#





re: VC++6.0中内存泄漏检测
2004-11-23 22:01

竹叶
——————–Configuration: test – Win32 Debug——————–

Compiling…

test.cpp

debug_new.cpp

Linking…

LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16

Debug/test.exe : fatal error LNK1120: 1 unresolved externals

Error executing link.exe.

test.exe – 2 error(s), 0 warning(s) 这是为何?





#





re: VC++6.0中内存泄漏检测
2004-12-24 05:02

JerryZ
很多人运行**的例子代码都没有得到预期的结果,我也是,我看了 MSDN 相关资料后明白了,也许是**留了一手,下面我来揭开谜底,呵呵:

1、检测内存泄漏的基本工具是调试器和 CRT 调试堆函数。为了使用调试堆函数,必须在要调试的程序中添加下面的语句:

#define _CRTDBG_MAP_ALLOC

#include<stdlib.h>

#include<crtdbg.h>

必须保证上面声明的顺序,如果改变了顺序,可能不能正常工作。<crtdbg.h>的_malloc_dbg和_free_dbg将取代标准的malloc和free函数出现在DEBUG版中,它可以跟踪内存的分配和释放。但是这只会在DEBUG版本中发生(当#define _DEBUG的时候),而Release版本仍使用标准的malloc和free功能。

#define _CRTDBG_MAP_ALLOC表示使用CRT堆函数的相应的DEBUG版本。这个定义不是必须的,但是没有它,内存泄漏报告中的信息不是很详细。

2、一旦你已经添加了刚才的声明,你就能够通过在程序中加入下面的代码来报告内存泄漏信息:

_CrtDumpMemoryLeaks();

当在DEBUG模式下运行程序时,在Output窗口的Debug页会显示内存泄漏的信息,例如:

Detected memory leaks!

Dumping objects ->

c:/program files/microsoft visual studio/vc98/include/crtdbg.h(552) : {45} normal block at 0x00441BA0, 2 bytes long.

Data: <AB> 41 42

c:/program files/microsoft visual studio/vc98/include/crtdbg.h(552) : {44} normal block at 0x00441BD0, 33 bytes long.

Data: < C > 00 43 00 CD CD CD CD CD CD CD CD CD CD CD CD CD

c:/program files/microsoft visual studio/vc98/include/crtdbg.h(552) : {43} normal block at 0x00441C20, 40 bytes long.

Data: < C > E8 01 43 00 16 00 00 00 00 00 00 00 00 00 00 00

Object dump complete.

MSDN 中讲得非常详细,有什么问题请大家多看多读,肯定会有收获。不啰嗦了。祝大家圣诞快乐!





#





re: VC++6.0中内存泄漏检测
2005-01-18 06:56

meteor135
我觉得只有这两个文件就够了,test.cpp中可以不显式出现任何处理动作,而由debug_new.cpp中的全局类变量的构造和析构过程完成。这样就摆脱了应用工程和调试工具的耦合。不知道大家对此有什么看法请评论。

注:工程中只需要加入debug_new.cpp

///

// test.cpp

#include <iostream>

using namespace std;

int main( void )

{

char* p = new char[2];

p[0] = ‘A’;

p[1] = ‘B’;

cout << “–End–” << endl;

return 0;

}

///

//debug_new.cpp

#ifdef _DEBUG

#include <windows.h>

#include <crtdbg.h>

class _DebugUtil

{

public:

_DebugUtil()

{

_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );

}

~_DebugUtil()

{

_CrtDumpMemoryLeaks();

}

} _debugUtil;

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 )

{

_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





#





re: VC++6.0中内存泄漏检测
2005-01-18 06:58

meteor135
上面的

void _RegDebugNew( void )

{

_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );

}

也不需要了。





#





to meteor135:
2005-01-18 21:56



周星星


谢谢!





#





re: VC++6.0中内存泄漏检测
2005-01-21 11:13

lift

#ifndef _DEBUG_NEW_H_

#define _DEBUG_NEW_H_

#ifdef _DEBUG

#ifdef new

#undef new

#endif

#define CRTDBG_MAP_ALLOC

#include <stdlib.h>

#include <crtdbg.h>

#include <windows.h>

namespace __impl {

class CCriticalSection {

public:

CCriticalSection() { ::InitializeCriticalSection( &m_cs ); }

~CCriticalSection() { ::DeleteCriticalSection( &m_cs ); }

void Enter() { ::EnterCriticalSection( &m_cs ); }

void Leave() { ::LeaveCriticalSection( &m_cs ); }

private:

CRITICAL_SECTION m_cs;

};

class CDumbCS {

public:

void Enter() { }

void Leave() { }

};

class CGuard {

public:

#ifdef _MT

typedef CCriticalSection lock_type;

#else

typedef CDumbCS lock_type;

#endif

static lock_type* GetLock() {

static lock_type lock;

return &lock;

}

public:

CGuard() { GetLock()->Enter(); }

~CGuard() { GetLock()->Leave(); }

};

class CDebugEnv {

public:

CDebugEnv() {

::_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

}

};

}

// normal

inline

void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine )

{

static __impl::CDebugEnv __dbgEnv;

__impl::CGuard guard;

return ::_malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );

}

// 当”new表达式调用的构造函数抛出异常”时可以正确地释放内存

inline

void __cdecl operator delete( void* p, const char* /*lpszFileName*/, int /*nLine*/ )

{

__impl::CGuard guard;

::_free_dbg( p, _NORMAL_BLOCK );

}

// normal

inline

void __cdecl operator delete( void* p)

{

__impl::CGuard guard;

::_free_dbg( p, _NORMAL_BLOCK );

}

#define new new(__FILE__, __LINE__)

#endif // _DEBUG

#endif





#





re: VC++6.0中内存泄漏检测
2005-01-21 11:22

lift
作为一个头文件包含就可以了,不需cpp文件

优化了单线程时的情况

全局对象初始化的问题已经考虑进去了

必须提供两个delete, 一个在new对象而构造函数抛出异常时由系统自动调用,一个为用户delete时调用





#





re: VC++6.0中内存泄漏检测
2005-02-12 22:07

achun
MS的crtdbg.h 真是莫名其妙!明明是

#ifndef _DEBUG

…..

#define _CrtSetDbgFlag(f)                   ((int)0)

那么在debug mode下应该无法使用_CrtSetDbgFlag的,他怎么用的呀?毫无道理!





#





re: VC++6.0中内存泄漏检测
2007-06-05 16:42

Aplia
会和Direct3D中的d3dx9math.h冲突





#





re: VC++6.0中内存泄漏检测
2007-06-12 10:20

x68251
我看了各位的评论,在我的代码中调试出现了下面的问题,请各位帮忙解决,谢谢!

Dumping objects ->

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/plex.cpp(29) : {213} normal block at 0x04AFBE60, 124 bytes long.

Data: <                > 00 00 00 00 00 00 00 00 06 0F 02 00 20 BB AF 04

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/map_pp.cpp(69) : {212} normal block at 0x04AFBDE0, 68 bytes long.

Data: <d               > 64 BE AF 04 00 00 00 00 00 00 00 00 00 00 00 00

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/plex.cpp(29) : {211} normal block at 0x04AFBD28, 124 bytes long.

Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 E0 BC AF 04

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/occcont.cpp(337) : {210} normal block at 0x04AFBCE0, 12 bytes long.

Data: <            > 00 00 00 00 20 BB AF 04 00 00 00 00

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/occmgr.cpp(781) : {190} client block at 0x04AFBB20, subtype c0, 236 bytes long.

a CCmdTarget object at $04AFBB20, 236 bytes long

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/plex.cpp(29) : {189} normal block at 0x04AFBA68, 124 bytes long.

Data: <            p   > 00 00 00 00 00 00 00 00 00 00 00 00 70 86 AF 04

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/occmgr.cpp(788) : {188} normal block at 0x04AF8670, 4 bytes long.

Data: < : x> DC 3A 1F 78

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/occmgr.cpp(143) : {183} client block at 0x04AFA330, subtype c0, 128 bytes long.

a CCmdTarget object at $04AFA330, 128 bytes long

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/ctlcore.cpp(574) : {179} client block at 0x04AFA0C8, subtype c0, 88 bytes long.

a CWnd object at $04AFA0C8, 88 bytes long

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/ctlview.cpp(239) : {159} normal block at 0x04AF9E30, 12 bytes long.

Data: <        L   > 01 00 00 00 00 00 00 00 4C F6 1D 00

./WebICTCtrl.cpp(14) : {150} client block at 0x04AF9B68, subtype c0, 652 bytes long.

a WebICTCtrl object at $04AF9B68, 652 bytes long

f:/rtm/vctools/vc7libs/ship/atlmfc/src/mfc/dllmodul.cpp(133) : {146} client block at 0x04AF9AE8, subtype c0, 64 bytes long.

a CDynLinkLibrary object at $04AF9AE8, 64 bytes long

{141} client block at 0x04AF85F0, subtype c0, 64 bytes long.

a CDynLinkLibrary object at $04AF85F0, 64 bytes long

{139} normal block at 0x04AF9808, 52 bytes long.

Data: <                > 08 98 AF 04 08 98 AF 04 08 98 AF 04 CD CD CD CD

{63} client block at 0x04AF3218, subtype c0, 64 bytes long.

a CDynLinkLibrary object at $04AF3218, 64 bytes long

Object dump complete.





#





re: VC++6.0中内存泄漏检测
2007-06-12 10:24

x68251
忘了说,我没有f盘,搜索也没有找到上面所说的.cpp文件.

怎样用它的内存编号调试???





#





re: VC++6.0中内存泄漏检测
2007-07-17 15:56

小字辈
MFC工程的程序 是不是有下面的就行了

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif





#





re 小字辈:
2007-07-17 18:07



周星星


MFC用向导生成的代码会自己加





#





re: VC++6.0中内存泄漏检测
2007-09-14 16:18

JUSTIN
# re: VC++6.0中内存泄漏检测 2004-12-24 05:02 JerryZ

应该不是这个文件有泄露才对 啊,应该是***。CPP





#





re: VC++6.0中内存泄漏检测
2007-12-04 11:01

Little_Char
我的工程很庞大 而且都是.c文件 编译环境是VS2005 请问能不能用以上的方法呢

另外我的大工程有很多.dsw工程 请问应该代码应该加在哪一个工程呢:是在大工程的main函数中 or 具体泄漏的地方??





#





re: VC++6.0中内存泄漏检测
2008-01-22 22:06



redwolf


好文章我放在我博客上了,不介意吧:)





#





re redwolf:
2008-01-23 09:20



周星星


当然不介意,请随意





#





re: VC++6.0中内存泄漏检测
2008-03-07 20:39

joycheney
好文章,可是出现:

nafxcwd.lib(afxmem.obj) : error LNK2005: “void * __cdecl operator new(unsigned int,char const *,int)” (??2@YAPAXIPBDH@Z) already defined in debug_new.obj

这句话怎么解决,不能忽略nafxcwd.lib,否则会出错,忽略afxmem.obj没有效果,怎么办?





#





re: VC++6.0中内存泄漏检测
2008-04-23 21:29

haohamaru
为什么我能确认已经释放的内存(在全局对象中分配的)输出时却仍然认为没被释放?我实在看不出为什么没有释放?





#





re: VC++6.0中内存泄漏检测
2008-06-25 10:38

xyj
好文章。刚打开字体也是小的,按着CTRL 和鼠标滚动轴  就OK了,:-)