使用Visual Studiodebugging器与不使用debugging器运行可执行文件之间的区别

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

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

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

这里是环境和结果:

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

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

基于这些结果,它看起来像运行“debugging”(即使在发布版本)以某种方式解决了这个问题。 这是否指向可能的罪魁祸首? 运行可执行文件与debugging和不运行之间有什么区别?

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

一个很好的debugging技巧帮助:写一个自定义的malloc,立即用完全随机的数据填充内存。 这样,在使用之前,您可以确保自己正确地初始化它,否则每次运行结果都会(希望)变得疯狂,即使在debugging模式下也是如此。

Solutions Collecting From Web of "使用Visual Studiodebugging器与不使用debugging器运行可执行文件之间的区别"

如果进程在调试器下启动,则Windows堆的行为将有所不同。 要禁用这种行为(为了在调试时发现问题)将_NO_DEBUG_HEAP = 1添加到环境中(就像在这个问题中一样 )。

或者,您可以在程序执行的早期附加处理。 那么堆将不会进入调试模式。 在执行开始的某个地方添加DebugBreak()行,使用Ctrl + F5运行,并在要求时开始调试。

那么,如果不了解你的代码,就很难说。 但是,我有一个程序做了大量的浮点运算(双精度数)类似的问题。

当我处理的数字稍有不同时,这个问题就会显现出来,但在数字上与机器无法区分。 如果两个双精度的numeric_limits<double>::epsilon()小于numeric_limits<double>::epsilon() ,则它们被视为与机器相同的编号。 因此,类型的表达式:

 if (num1==num2)... 

要么

 if (num1<num2)... ... 

可以导致多彩的效果。

在调试或发布模式下运行时,这些多彩效果可能会有所不同 原因是调试/发布运行时库是不同的。 而且,关键的是,编译是通过不同的代码优化来完成的。 命令行调试版本和调试窗口版本(F5)之间的区别也可以通过细微的优化差异来解释。

如果您使用的是VS,您可以在Properties菜单的C/C++Linker部分查看不同的编译选项和优化的效果。

为了避免这个问题,我建议使用<limits> STL库中的numeric_limits工具。 作为一个例子,一个小于运算符的实现应该是这样的:

 bool operator<(double num1, double num2) { double difference=fabs(num1-num2); if (difference>numeric_limits<double>::epsilon()) { if (num1 < num2) return true; return false; } return false; }