11

我所谓的确定性程序在不同的运行中产生了几个略有不同的输出之一。输入、编译器和计算机是不变的。我不确定哪个输出是正确的,因为它看起来总是合理的。

除了对 rand() 的杂散调用之外,这怎么可能呢?

4

12 回答 12

18

在几个方面:

  • 以涉及数据竞争的方式使用多个线程,
  • 使用当前系统时间作为输入,
  • 使用未初始化的变量,
  • ...

我们当然可以做出更多的猜测,但是如果您想获得有意义的帮助,发布代码的相关部分可能对您有好处:-)

于 2010-08-31T13:32:42.663 回答
8

如果您的输出取决于堆上分配的地址:

int main(int argc, char* argv[])
{
   printf("%p", malloc(42));
   return 0;
}

对于每次运行, malloc() 可能会返回不同的虚拟地址 - 更不用说 NULL 以防分配失败。

于 2010-08-31T13:59:45.513 回答
7

它可能是:

  • 线程计时
  • 任何类型的输入(用户、文件、网络等)
于 2010-08-31T13:31:59.883 回答
5

如果您的程序使用浮点/双精度,如果在某些架构上有上下文切换,结果可能会有所不同。

在 x86 上,FPU 使用扩展精度作为中间结果,但是当保存在内存中时(当存在进程或线程的上下文切换时会发生这种情况),这种精度会丢失。这可能会导致结果出现一些小的差异(我们在程序中检测到了这样的问题)。避免此问题的一种方法是要求编译器不要使用 FPU 而是使用 SSE 进行浮点运算。

http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html

于 2010-09-01T09:50:31.313 回答
4

除了对 rand() 的杂散调用

rand()只要你给它提供相同的初始种子,它就是完全确定的。

于 2010-08-31T15:25:51.437 回答
3

在没有看到一些代码(提示提示)的情况下,我能想到的最好的方法就是寻找一种模式。也许是特定日期时间的东西。

另外,尝试寻找比赛条件。这看起来是不确定的。

于 2010-08-31T13:32:51.290 回答
2

使用指针的值而不是它所指向的值总是会产生有趣的结果。

于 2010-08-31T15:18:53.973 回答
1

在与“外部世界”交互不多的程序中,不确定性的流行来源是对指针比较的依赖。有时您可能会在代码中看到它:当字典比较函数用完要比较的东西(一切都相等)时,它会比较对象的地址作为最后的手段。如果在动态内存中分配对象,这可能会产生不同的顺序,因为实际分配位置可能因平台和运行而异。

于 2010-08-31T17:20:18.497 回答
0

显然是月相错误的一个新实例。

于 2010-08-31T17:10:07.983 回答
0
  • 来自网络/互联网的输入。
  • 约会时间
于 2010-08-31T17:12:17.743 回答
0

你没有提供很多信息。然而,作为一个以实时编程为生的人,当这种事情发生时,我寻找的最有可能的罪魁祸首是:

  • 使用未初始化的内存。
  • 比赛条件。
  • 以上的一些晦涩的组合。

例如,我曾经遇到的一个这样的麻烦归结为共享库不像我想象的那样“共享”,并试图使用一个进程的句柄来索引一个尚未在第二个进程中初始化的表。取决于事情的启动方式,可能会或可能不会导致第三个进程中的重要数据被丢弃。

于 2010-08-31T17:40:28.270 回答
0

任何未定义的行为。即:需要数百页来解释输出更改的每个可能来源。尝试调试以查找发生更改的位置,或阅读一些 C++ 规范。

于 2010-08-31T17:44:21.523 回答