_CrtSetAllocHook无法显示文件名/行号

3
我正在实现一个内存跟踪器,以便在将来的某个时间点,如果出现任何内存泄漏,我可以启动这个小家伙来找到它。
一切都很好,除了我从未得到文件名或行号。是否有一些标志我需要使用_CrtSetDbgFlag设置,或者一个预处理器命令?
运行程序(只是基本架构),它显示了26个未清理的分配,我非常确定它们不是我的,但不知道它们出现在哪里。
提前致谢!

你有没有考虑使用vld而不是自己编写代码? - Björn Pollex
@Space_C0wb0y,谢谢你提供的链接,我会去看看。但是这也是一个理解CRT调试功能的练习(我希望很快也能捕获堆栈),并且在某种程度上深入了解内部工作原理 :) - Moo-Juice
1个回答

4

来自<crtdbg.h>头文件:

#ifdef  _CRTDBG_MAP_ALLOC
#define   malloc(s)             _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
// etc...
#endif

请注意,重新定义现在调用了另一个具有您要查找的文件和行号的malloc版本。显然,为使此工作正常,您将不得不#define _CRTDBG_MAP_ALLOC并#include crtdb.h。最好在您的预编译头文件中完成此操作,以便您可以相当确信所有代码都将使用这些宏进行编译。
但这仍然不能保证您能够获得此信息。您的项目可能正在使用没有编译此信息的.lib。另一种故障模式是DLL可能会在生成泄漏报告之前被卸载。该DLL的文件和行信息也将被卸载。
对于这些麻烦制造者的诊断有后备措施。泄漏报告的一行泄漏以花括号内部开始的块编号开头。只要该块编号在运行之间保持稳定,您就可以强制调试器在进行分配时中断。将此代码放入主方法或代码中较早执行的任何点:
 _crtBreakAlloc = 42;   // Change the number

嗨,感谢您的回复。我按照您上面概述的方式实现了宏和包含到我的核心头文件中(该文件被预编译),但仍然没有传递任何文件名(我使用断点进行了检查)。我是否还遗漏了其他内容?(也感谢您提供的知情回复) - Moo-Juice
注意:在调试器中,我看到它仍然通过常规的malloc调用进行。 - Moo-Juice
好的,这就解释了。为什么它不使用重新定义是我无法猜测的。请确保_CRTDBG_MAP_ALLOC已经被#defined,并通过查看预处理器输出来排除预处理器错误。 - Hans Passant
我理解从你的角度来看可能很难 :) 在我的核心头文件中,我使用 #define _CRTDBG_MAP_ALLOC(我甚至检查了拼写,甚至复制了 <crtdbg.h> 中的定义),然后直接在其后包含 <crtdbg.h>。无论如何,我会尽力而为,你的答案是正确的,因此将被标记为正确 :) 感谢你的时间。 - Moo-Juice

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