SDL内存泄漏和Visual Leak Detector

4
好的,我认为我的程序可能存在内存泄漏。它是一个SDL应用程序,似乎已经变得太大了,以至于我无法手动定位泄漏。我寻找了一个与Valgrind相当的Windows工具(我正在运行Windows 7 x64并使用Visual Studio 2010),最终找到了Visual Leak Detector。不幸的是,它似乎不想生成任何输出。
我设置了另一个项目,一个空的控制台应用程序,并像在我的SDL应用程序中一样设置了VLD。运行程序后,VLD完美地工作并捕获了我遇到的每个内存泄漏。但在SDL应用程序中,即使我故意在主函数中创建内存泄漏,它也只在调试会话开始时输出“Visual Leak Detector Version 2.2 installed.”,什么都没有输出。
我能想到的最接近的可能是与SDL搞乱了程序入口有关。但这只是一个猜测。是否有办法让VLD与SDL一起工作?

你是否找到了解决那个问题的方法?我现在也遇到了完全相同的问题,而且我几乎采取了和你一样的步骤。独立运行时它可以工作,但与SDL一起就不行。 - ForceMagic
2个回答

2
您可以尝试使用 deleaker。它是一款强大的用于调试内存泄漏的工具。

0

我之前也遇到了使用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); // Memory not freed

    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 ); // Nothing in both case!

    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符号可能没有被定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接