使用 _crtBreakAlloc 查找内存泄漏 - 标识符“_crtBreakAlloc”未识别
Using _crtBreakAlloc to find memory leaks - identifier "_crtBreakAlloc" is unidentified
我正尝试按照 this link 中的建议在 Watch window 中使用 _crtBreakAlloc
,但值行显示 'identifier "_crtBreakAlloc" is unidentified' 并且它根本行不通。
我做错了什么?顺便说一句,我正在使用Visual Studio。
代码示例:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <malloc.h>
int main()
{
int *arr = (int*)malloc(10 * sizeof(int)); //breakpoint here
free(arr);
return 0;
}
然后我将 _crtBreakAlloc 写入 Watch 的 Name 字段 window 并在遇到断点时回车。
如果您使用的是多线程版本的 CRT,请在
观看 window(在列名中):
(int*){,,ucrtbased.dll}_crtBreakAlloc
然后按 enter 并将值 -1 更改为导致 user-defined 断点的新分配编号。
看来Visual Studio 2015需要用两个下划线:
(int*){,,ucrtbased.dll}__crtBreakAlloc
_crtBreakAlloc
是 VS2015 下的一个宏,它被替换为调用返回一个 int 指针的函数。在手表中跟踪变量 window 似乎不是一个选项。
最好在你的(调试)代码中插入这样的东西:
_crtBreakAlloc = 18;
{,,ucrtbased.dll}*__p__crtBreakAlloc()
适用于 Visual Studio 2017
如果未加载 ucrtbased.dll 符号,_crtBreakAlloc 将被报告为未识别。我遇到这个问题是因为我不会自动加载我的符号。您可以进入模块列表并手动加载 ucrtbased.dll 的符号,然后 _crtBreakAlloc 应该会出现并工作。
几个选项:
- 添加 {,ucrtbased.dll }_crtBreakAlloc 作为观察变量
这需要加载符号以便 watch window 正确显示变量类型
找出你编译的 CRT 版本 crt*.dll。 (新的 ucrtbased.dll,旧的 msvcrtd*.dll 等)
https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2019
加载所有模块,或手动添加到 \tools\options\debug\symbols\load 只有规范模块
注意:您的调试配置使用 /MDd 编译(它将定义 _DEBUG)
使用 /MD 发布配置编译(大多数调试宏只是零;)
- 使用下面的 memchk_break 宏,它会自动在本地显示分配块
(因为它通过编译解决)
- 让它 运行,传递第一次中断,让它打印内存泄漏(如果有的话)
- 在第二轮中,将 alloc 块键入变量 运行 和 catch
#ifdef _DEBUG
#define memchk_break() { auto& _ab = _crtBreakAlloc; __debugbreak(); }
#else
#define memchk_break() 0;
#endif
void main(){
memchk_break();
// your code
_CrtDumpMemoryLeaks();
}
我正尝试按照 this link 中的建议在 Watch window 中使用 _crtBreakAlloc
,但值行显示 'identifier "_crtBreakAlloc" is unidentified' 并且它根本行不通。
我做错了什么?顺便说一句,我正在使用Visual Studio。
代码示例:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <malloc.h>
int main()
{
int *arr = (int*)malloc(10 * sizeof(int)); //breakpoint here
free(arr);
return 0;
}
然后我将 _crtBreakAlloc 写入 Watch 的 Name 字段 window 并在遇到断点时回车。
如果您使用的是多线程版本的 CRT,请在 观看 window(在列名中):
(int*){,,ucrtbased.dll}_crtBreakAlloc
然后按 enter 并将值 -1 更改为导致 user-defined 断点的新分配编号。
看来Visual Studio 2015需要用两个下划线:
(int*){,,ucrtbased.dll}__crtBreakAlloc
_crtBreakAlloc
是 VS2015 下的一个宏,它被替换为调用返回一个 int 指针的函数。在手表中跟踪变量 window 似乎不是一个选项。
最好在你的(调试)代码中插入这样的东西:
_crtBreakAlloc = 18;
{,,ucrtbased.dll}*__p__crtBreakAlloc()
适用于 Visual Studio 2017
_crtBreakAlloc 将被报告为未识别。我遇到这个问题是因为我不会自动加载我的符号。您可以进入模块列表并手动加载 ucrtbased.dll 的符号,然后 _crtBreakAlloc 应该会出现并工作。
几个选项:
- 添加 {,ucrtbased.dll }_crtBreakAlloc 作为观察变量
这需要加载符号以便 watch window 正确显示变量类型
找出你编译的 CRT 版本 crt*.dll。 (新的 ucrtbased.dll,旧的 msvcrtd*.dll 等)
https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2019
加载所有模块,或手动添加到 \tools\options\debug\symbols\load 只有规范模块
注意:您的调试配置使用 /MDd 编译(它将定义 _DEBUG)
使用 /MD 发布配置编译(大多数调试宏只是零;)
- 使用下面的 memchk_break 宏,它会自动在本地显示分配块
(因为它通过编译解决)
- 让它 运行,传递第一次中断,让它打印内存泄漏(如果有的话)
- 在第二轮中,将 alloc 块键入变量 运行 和 catch
#ifdef _DEBUG
#define memchk_break() { auto& _ab = _crtBreakAlloc; __debugbreak(); }
#else
#define memchk_break() 0;
#endif
void main(){
memchk_break();
// your code
_CrtDumpMemoryLeaks();
}