C++ 如何诊断Windows上的堆损坏错误?
我使用的是64位Windows 8.1和Visual Studio 2013 Ultimate。我正在移植一个程序,从Linux到Windows,使用C++、OpenGL和SDL。我通过64位Windows上的cmake自定义编译了相应的库。当我从VisualStudio运行程序时,IDE说有一个头部损坏。这并不奇怪,因为我正在使用指针来实例化对象,并且我正在使用原始指针,为了参数起见,我确实计划将其更改为智能指针。我稍后会做助推魔法 同时,我用我的Linux计算机诊断Valgrind的内存泄漏,Valgrind没有报告任何严重的情况。然后我继续使用CppCheck,但也没有什么严重的问题。也许我在这里太宽容了,Windows实际上可能比Linux更严肃地对待那些不那么严肃的东西,这是一个惊喜,因为MSVC往往比GCC更宽容 因此,该程序可以在Linux上运行,而不能在Windows上运行。(太棒了!)而VisualStudio并没有帮上忙,它到处抛出异常,这让我更讨厌Windows。我开始在谷歌上搜索解决方案,遇到了一个叫做gflags或page helper的东西,所以我安装了调试工具并尝试启动gflags,但我不知道如何使用它!后来我发现,你必须使用另一种叫做adp的工具,然后将gflags附加到它上,所以当我启动adp时,它崩溃了。因此,现在我不知道该怎么做,即将放弃这个端口(这很有趣,因为很多人都在抱怨将程序从Windows移植到Linux是多么困难,而事实恰恰相反)C++ 如何诊断Windows上的堆损坏错误?,c++,linux,windows,opengl,visual-studio-2013,C++,Linux,Windows,Opengl,Visual Studio 2013,我使用的是64位Windows 8.1和Visual Studio 2013 Ultimate。我正在移植一个程序,从Linux到Windows,使用C++、OpenGL和SDL。我通过64位Windows上的cmake自定义编译了相应的库。当我从VisualStudio运行程序时,IDE说有一个头部损坏。这并不奇怪,因为我正在使用指针来实例化对象,并且我正在使用原始指针,为了参数起见,我确实计划将其更改为智能指针。我稍后会做助推魔法 同时,我用我的Linux计算机诊断Valgrind的内存泄漏
所以,现在我向这个社区寻求帮助:如何调试/诊断Windows上而不是Linux上发生的堆损坏错误?我真的应该使用gflags吗?还是我应该在这方面使用我的勇气?使用调试堆并在main()中一开始调用它
\u CRTSETDBG标志(\u CRTDBG\u检查\u始终\u DF)代码>
这将大大降低程序的运行速度,但一旦发生腐败,程序就会崩溃
有关详细信息,请参阅本文:对于较小的问题,@Carlos的解决方案是完美的。但对于巨大的问题,导致的减速有时是你无法忍受的
在这种情况下,可以将
ASSERT(_CrtCheckMemory());
在代码的某个地方,人们怀疑问题已经存在。此命令在插入堆的位置(且仅在插入堆的位置)检查堆,而不是在每次new
或delete
调用后检查堆,就像\u CRTDBG\u CHECK\u ALWAYS\u DF
的情况一样。与选项\u CRTDBG\u CHECK\u ALWAYS\u DF
相比,这使执行时间保持合理
通过使用二进制搜索(一种放置断言的方法)可以很快找到有问题的代码行
但是,有时\u crtsetdbglafg(\u CRTDBG\u CHECK\u ALWAYS\u DF)
和/或\u CrtCheckMemory()
无法检测问题。然后使用gflags
是另一种可能性,它能够显示堆损坏发生的位置:
- 启用页堆,例如:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" -p /enable exe_to_debug.exe /full
- 在调试器中运行程序。访问越界,这会损坏堆,导致访问冲突,并且很容易在调试器中看到
- 调试完成后禁用页面堆,例如:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" -p /disable exe_to_debug.exe
VS具有内置内存泄漏检测器:您使用过调试器吗?您也可以在linux上尝试使用铿锵的sanatizers。也许他们发现了valgrind和cpp check没有发现的东西。对不起,我好久没回复了。我仍然有这个问题,但它似乎来自外部.dll文件。我不确定这是否是我这边的问题,只需说访问冲突0xFF错误很烦人就够了!谢谢你的回复。我从未见过这个调试函数,所以它会很有趣。好东西!