我之前也遇到了使用SDL库的类似问题。不过在我的情况下,我尝试使用Visual Studio 2010的默认内存泄漏检测,因为我不想使用第三方库或应用程序。
解决问题
如果在所有必需的包含、定义和函数调用之后,仍然没有看到任何内存泄漏的输出,可能是你的运行时库设置不正确。
请仔细检查是否使用了调试版本的运行时库,而不是非调试版本(/MT 和 /MD)。
多线程调试 (/MTd)
多线程调试 DLL (/MDd)
当你指定 /MTd 或 /MDd 选项时,编译器会定义 _DEBUG。这些选项指定了 C 运行时库的调试版本。参见 MSDN 上的 _DEBUG 参考文档
因此,必须定义 _DEBUG 符号才能启用 CRT 代码。
[...] 当未定义_DEBUG时,在预处理期间会删除对_CrtSetDbgFlag的调用[...]。
请参阅MSDN参考资料
因此,构建调试版本并不能确保定义了_DEBUG。
这通常是在正常项目中不需要更改的内容,但是按照SDL教程操作可能会导致你遇到我遇到的问题。
希望这能帮助其他人,甚至是你自己。
以下是更多细节
我正在按照MSDN页面启用VS 2010中的内存泄漏检测。
在声明了那些变量之后,
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
我将它们启用到我的代码中,并插入了一个故意的内存泄漏
int main( int argc, char* args[] )
{
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
int *pArray = (int*)malloc(sizeof(int) * 24);
return 0;
}
没有任何东西被打印出来。
所以,我查看了汇编代码,发现它明显根本没有生成CRT代码,如下所示:
int main( int argc, char* args[] )
{
012932F0 push ebp
012932F1 mov ebp,esp
012932F3 sub esp,0CCh
012932F9 push ebx
012932FA push esi
012932FB push edi
012932FC lea edi,[ebp-0CCh]
01293302 mov ecx,33h
01293307 mov eax,0CCCCCCCCh
0129330C rep stos dword ptr es:[edi]
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF )
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG )
int *pArray = (int*)malloc(sizeof(int) * 24)
0129330E mov esi,esp
01293310 push 60h
01293312 call dword ptr [__imp__malloc (129E4CCh)]
01293318 add esp,4
0129331B cmp esi,esp
0129331D call @ILT+580(__RTC_CheckEsp) (1291249h)
01293322 mov dword ptr [pArray],eax
然后,我意识到_DEBUG符号可能没有被定义。