最近研究开源数据地球系统osgearth的开发,基于vc.net2010,采用sp1包里的ribbon风格搭建mfc的单文档应用程序,按照osgearth提供的example例子完成简单的地球显示和模型加载,每次系统退出时发现大量的内存泄露问题,还以为是因为智能指针没用好,自己犯了基础的错误,将自己的代码看了又看没找到内存泄露的原因,最后网上找到了原因,应该是MFC的一个bug或issue,如下:
There is a known issue/BUG with MFC, were MFC makes a call to
_CrtDumpMemoryLeaks() in the destructor of the _AFX_DEBUG_STATE, followed by _CrtSetDbgFlag() which sets it to ~_CRTDBG_LEAK_CHECK_DF (therefor disabling memory leak test at *true* program exit) This destructor is called at exit (i.e. atexit()), but before statics residing in dlls and others are destroyed, resulting in many false memory leaks are reported
参考资料链接是:
1. Why does my OSG MFC based application show memory leaks。
2. 在MFC框架下使用osg报内存泄露的解决办法
简单说一下泄露问题的发现和解决过程:
让输出窗口在程序退出时输出内存泄露信息,需要在可能存在内存泄露的文件头部添加下面的宏:
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
.....
{184} normal block at 0x00FB7510, 24 bytes long.
Data: < u u u > 10 75 FB 00 10 75 FB 00 10 75 FB 00 CD CD CD CD
{183} normal block at 0x00FB7150, 896 bytes long.
Data: < > 00 00 00 00 CD CD CD CD CD CD CD CD CD CD CD CD
{181} normal block at 0x00FB70A0, 24 bytes long.
Data: < a > D8 61 15 00 FF FF FF FF 00 00 00 00 00 00 00 00
{180} normal block at 0x00FB6FE0, 128 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{179} normal block at 0x00FB6F20, 128 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{178} normal block at 0x00FB6E60, 128 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{137} normal block at 0x00FB6D98, 136 bytes long.
Data: < WC > D8 57 43 10 00 00 00 00 01 00 00 00 00 00 00 00
{135} normal block at 0x00FB6C58, 64 bytes long.
Data: <OpenThread v1.2p> 4F 70 65 6E 54 68 72 65 61 64 20 76 31 2E 32 70
....
这个是网上给出的解决方法:
In your MFC application.
. Goto project settings. In there, make the following changes for theDebug build.
. General->Use of MFC->Use Standard Windows Libraries.
. Add _AFXDLL to C/C++->Preprocessor->Preprocessor Definitions.
. Add mfc80??.lib (in my case it is mfc80ud.lib) as a first dependency or at least before osg libs to Linker->Input->Additional
Dependencies.
还需要将unicode变为多字节编码,重新clean build 通过。