使用_crtBreakAlloc来查找内存泄漏 - 标识符“_crtBreakAlloc”未定义。

11
我试图在观察窗口中使用_crtBreakAlloc,如链接所建议的那样,但是值行显示“标识符“_crtBreakAlloc”未定义”,它根本不起作用。

我做错了什么?顺便说一下,我正在使用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"写入“Name”字段中的监视窗口,并按回车键。


请确保您正在使用调试版本 (/MTd/MDd)。 - cremno
我应该把这些标志放在哪里? - Sunspawn
听起来像是编程问题。请发布代码。否则我们只能猜测。 - user3629249
@Sunspawn:除非你已更改项目属性(C/C++ -> 代码生成),否则只需使用 Debug 而不是 Release 配置。另外,请确保执行以下操作:如果你正在使用多线程 DLL 版本的 CRT 库(/MD选项),请包含上下文运算符:{,,msvcr100d.dll}_crtBreakAlloc (对于 VS2013,它是 msvcr120d)。 - cremno
我正在使用默认的 F5 调试模式。这有什么不同吗? - Sunspawn
好的,显然我之前使用了/MD选项 - 现在它告诉我“找不到msvcr100d.dll模块”,尽管它就在System32文件夹中。 - Sunspawn
6个回答

9
如果未加载ucrtbased.dll符号,则_crtBreakAlloc将报告为未定义。我遇到了这个问题,因为我没有自动加载我的符号。您可以进入模块列表并手动加载ucrtbased.dll的符号,然后_crtBreakAlloc应该出现并正常工作。

遇到了同样的问题!请注意,这适用于例如使用{,,ucrtbased.dll}_crtBreakAlloc的VS 2019,正如其他答案所建议的那样。很可能这个页面可以用来猜测将来版本中应该使用的任何符号名称 - Visual Studio文档 - stoper

4

_crtBreakAlloc是VS2015中的一个宏,它被替换为调用一个返回指向整型变量的指针的函数。在监视窗口中跟踪变量似乎不是一个好选择。
最好在您的(调试)代码中插入类似以下的语句:

_crtBreakAlloc = 18;

4

几个选项:
- 添加{,,ucrtbased.dll }_crtBreakAlloc作为Watch的变量
这需要加载符号,以便监视窗口正确显示变量类型

找出你编译的CRT版本是哪个crt*.dll(新的ucrtbased.dll、旧的msvcrtd*.dll等)
https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2019
加载所有模块,或手动添加到\tools\options\debug\symbols\load only spec modules
注意:您的Debug配置使用/MDd进行编译(它将定义_DEBUG)
Release配置使用/MD进行编译(大多数调试宏只是零;)


- 使用下面的memchk_break宏,它会自动在locals中显示alloc block
(因为它通过编译解析)


- 让它运行,在第一个中断时忽略,如果有任何内存泄漏,则让它打印
- 在第二轮中,输入分配块到变量,运行并捕获


#ifdef _DEBUG
   #define memchk_break() { auto& _ab = _crtBreakAlloc; __debugbreak(); }
#else
   #define memchk_break() 0;
#endif
void main(){
   memchk_break();
   // your code
   _CrtDumpMemoryLeaks();
}

3
{,,ucrtbased.dll}*__p__crtBreakAlloc()

适用于Visual Studio 2017


2
如果您正在使用 CRT 的多线程版本,请在观察窗口中输入以下内容(在列名称中):
(int*){,,ucrtbased.dll}_crtBreakAlloc

然后按回车键并将值-1更改为导致用户定义断点的新分配号码。 enter image description here

0

看起来在使用Visual Studio 2015时需要使用两个下划线:

(int*){,,ucrtbased.dll}__crtBreakAlloc

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