我正在尝试调试一个问题,即当直接从Visual Studio执行可执行文件时会产生可重复的输出(这是我想要的),但是从命令提示符执行时不会产生可重复的输出。它是单线程应用程序,因此在时间方面不应该有任何奇怪的行为。
有人能列举一下两种环境之间可能存在的差异吗?
我确定实际的可执行文件是相同的——它们都是发布版本,并且运行相同的.exe文件。
以下是环境和结果:
- 从命令提示符(cmd)直接运行:不可重复的输出
- 使用调试运行Visual Studio(F5):可重复的输出
- 在没有调试的情况下从Visual Studio运行(Ctrl-F5):不可重复的输出
我知道工作目录可能不同,但我手动调整它以确保工作目录是相同的。
基于这些结果,看起来“使用调试运行”(即使在发布构建中)以某种方式修复了问题。这指向了一个可能的罪魁祸首吗?使用调试和不使用调试运行可执行文件之间有哪些差异?
解决方案:如最佳答案中所指出的,调试堆是问题所在。问题是我们代码深处有人在初始化数组的部分之前访问了数组的某些部分。他们使用malloc分配了内存,并未将内存初始化为0。我认为调试堆会用某个可重复的值填充数组,而当没有附加调试器时(即从命令行或使用Ctrl-F5运行时)值更随机,有时会导致程序行为的微小偏差。不幸的是,这种微调几乎不容易被注意到,而且涉及的内存在第一帧处理后已经正确重置,但是初始条件已经略有不同,损坏已经造成。这就是混沌理论!感谢指导。
一个很好的调试提示是:编写自定义 malloc,它会立即使用完全随机的数据填充内存。这样,您可以确保在使用之前正确初始化它,否则每次运行时您的结果将(希望是)非常奇怪 - 即使在调试模式下使用调试堆!