使用Visual Studio调试器与不使用调试器运行可执行文件之间的差异

aar*_*rkk 15 c++ windows visual-studio-2010 visual-studio

我正在尝试调试一个问题,其中可执行文件直接从Visual Studio执行时产生可重复输出(我想要),但在从命令提示符执行时不会产生可重复输出.它是一个单线程应用程序,所以在时间方面不应该有任何奇怪的行为.

有人可以列举两种环境之间可能存在的差异吗?

我确定实际的可执行文件是相同的 - 它们都是发布版本并运行相同的.exe文件.

以下是环境和结果:

  1. 直接从命令提示符(cmd)运行:不可重复的输出
  2. 从带有调试的Visual Studio(F5)运行:可重复输出
  3. 从Visual Studio运行而不进行调试(Ctrl-F5):不可重复的输出

我知道工作目录可能有所不同,但我手动调整它以确保工作目录是相同的.

基于这些结果,看起来像运行"with Debugging"(即使在Release版本中)以某种方式修复了问题.这是否可能是罪魁祸首?运行可执行文件与调试之间有什么区别?

解决方案:正如在接受的答案中指出的那样,调试堆就是问题所在.问题是我们代码的内部深处,有人在初始化之前访问大型数组的部分内容.他们已经用malloc分配了内存并且没有将内存初始化为0.调试堆将(我假设)用一些可重复的值填充数组,而当调试器没有附加时(即从命令行运行或与Ctrl-F5)值更随机,有时会导致程序行为的微小偏差.不幸的是,调整是如此微妙以至于几乎不可察觉,并且在处理的第一个"帧"之后,所讨论的存储器正确地重置,但是初始条件已经略有不同并且损坏已经完成.混沌理论在行动!感谢您的指导.

一个很好的调试技巧帮助:编写一个自定义的malloc,立即用完全随机的数据填充内存.这样,你可以确保在使用它之前自己正确地初始化它,否则每次运行它时你的结果都会(希望)疯狂 - 即使在调试堆的调试模式下!

Dia*_*cus 17

如果在调试器下启动进程,则Windows堆的行为会有所不同.要禁用此行为(为了在调试时发现问题),请将_NO_DEBUG_HEAP = 1添加到环境中(如此问题).

或者,您可以在程序执行的早期附加到进程.Heap将不会进入调试模式.DebugBreak()在执行开始的某处添加行,使用Ctrl + F5运行,并在被要求时开始调试.