- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试找出内存泄漏问题。
我的项目是一个基于 ATL 的对话框项目,它使用 DirectShow 和标准库。
我的程序中总共有 45 个内存泄漏,每个都是 24 个字节。
我在我的 stdafx.h 中 #define'd _CRTDBG_MAP_ALLOC 等,以及 DEBUG_NEW 以获取每个内存泄漏的文件和行号。
但是,没有打印文件行号。内存块都是“普通” block ,看起来像这样:
{180} normal block at 0x003E6008, 24 bytes long. Data: < > _> > W > A0 AE 3E 00 B0 5F 3E 00 A0 AE 3E 00 57 00 00 00
我尝试将以下行添加到 _tWinMain() 的开头
_CrtSetBreakAlloc(180);
为了中断分配,但调试器根本没有中断。
谁能告诉我如何追踪难以捉摸的内存泄漏?
最后,这是我的 _tWinMain() - 我在退出之前调用了 _CrtDumpMemoryLeaks()。
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow){
_CrtSetBreakAlloc(180);
HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
ATLASSERT(SUCCEEDED(hRes));
::DefWindowProc(NULL, 0, 0, 0L);
AtlInitCommonControls(ICC_BAR_CLASSES);
//HINSTANCE hInstRich = ::LoadLibrary(CRichEditCtrl::GetLibraryName());
hRes = _Module.Init(NULL, hInstance);
ATLASSERT(SUCCEEDED(hRes));
int nRet = Run(lpstrCmdLine, nCmdShow);
_Module.Term();
::CoUninitialize();
_CrtDumpMemoryLeaks();
return nRet;
}
最佳答案
两个建议。
首先,在main
(或等同的)开始之前构造的东西在main
完成后被销毁。在 main
末尾调用 _CrtDumpMemoryLeaks
可能会给您误报。 (或者它们是漏报?)全局对象的析构函数尚未运行,atexit
回调尚未运行,因此泄漏输出将包括尚未正确释放的分配。
(我怀疑这就是您的全局对象出现泄漏的原因。代码很可能没有任何问题,而且实际上它很可能正在正确地 self 清理——当 时,清理代码还没有运行_CrtDumpMemoryLeaks
正在被调用。)
您需要做的是指示运行时库为您调用 _CrtDumpMemoryLeaks
,就在最后,在所有 atexit
回调和全局对象析构函数都已完成之后完成的。然后你只会看到真正的泄漏。这段代码可以解决问题。坚持在 main
的开头:
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)|_CRTDBG_LEAK_CHECK_DF);
其次,如果上面的内容揭示了在 main
之前运行的东西的真正泄漏,您可以做一些小技巧,让您自己的一些代码在其他任何东西被查看之前运行。然后您可以在任何分配发生之前设置 _crtBreakAlloc
。只需将以下代码弹出到它自己的 .cpp 文件中:
#include <crtdbg.h>
#ifdef _DEBUG
#pragma warning(disable:4074)//initializers put in compiler reserved initialization area
#pragma init_seg(compiler)//global objects in this file get constructed very early on
struct CrtBreakAllocSetter {
CrtBreakAllocSetter() {
_crtBreakAlloc=<allocation number of interest>;
}
};
CrtBreakAllocSetter g_crtBreakAllocSetter;
#endif//_DEBUG
(我怀疑编译器的 init 段中的代码很可能在 stdin
和 stdout
等被初始化之前运行,当然在任何全局对象被构造之前,所以你可能很难做任何比上面更复杂的事情!)
(就其值(value)而言,我最近认为,并且已经有一段时间了,在 main
开始之前分配几乎总是一件坏事。这使得很难自己清理干净,很难跟踪发生了什么。这当然很方便,但你似乎总是要晚些时候为此付出代价。尽管如此,这个建议说起来比实现起来容易得多,尤其是作为一部分一个更大的团队。)
关于c++ - 内存泄漏 : unable to break on a memory allocation number,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3118741/
我是一名优秀的程序员,十分优秀!