我所谓的确定性程序在不同的运行中产生了几个略有不同的输出之一。输入、编译器和计算机是不变的。我不确定哪个输出是正确的,因为它看起来总是合理的。
除了对 rand() 的杂散调用之外,这怎么可能呢?
我所谓的确定性程序在不同的运行中产生了几个略有不同的输出之一。输入、编译器和计算机是不变的。我不确定哪个输出是正确的,因为它看起来总是合理的。
除了对 rand() 的杂散调用之外,这怎么可能呢?
在几个方面:
我们当然可以做出更多的猜测,但是如果您想获得有意义的帮助,发布代码的相关部分可能对您有好处:-)
如果您的输出取决于堆上分配的地址:
int main(int argc, char* argv[])
{
printf("%p", malloc(42));
return 0;
}
对于每次运行, malloc() 可能会返回不同的虚拟地址 - 更不用说 NULL 以防分配失败。
它可能是:
如果您的程序使用浮点/双精度,如果在某些架构上有上下文切换,结果可能会有所不同。
在 x86 上,FPU 使用扩展精度作为中间结果,但是当保存在内存中时(当存在进程或线程的上下文切换时会发生这种情况),这种精度会丢失。这可能会导致结果出现一些小的差异(我们在程序中检测到了这样的问题)。避免此问题的一种方法是要求编译器不要使用 FPU 而是使用 SSE 进行浮点运算。
http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html
除了对 rand() 的杂散调用
rand()
只要你给它提供相同的初始种子,它就是完全确定的。
在没有看到一些代码(提示提示)的情况下,我能想到的最好的方法就是寻找一种模式。也许是特定日期时间的东西。
另外,尝试寻找比赛条件。这看起来是不确定的。
使用指针的值而不是它所指向的值总是会产生有趣的结果。
在与“外部世界”交互不多的程序中,不确定性的流行来源是对指针比较的依赖。有时您可能会在代码中看到它:当字典比较函数用完要比较的东西(一切都相等)时,它会比较对象的地址作为最后的手段。如果在动态内存中分配对象,这可能会产生不同的顺序,因为实际分配位置可能因平台和运行而异。
显然是月相错误的一个新实例。
你没有提供很多信息。然而,作为一个以实时编程为生的人,当这种事情发生时,我寻找的最有可能的罪魁祸首是:
例如,我曾经遇到的一个这样的麻烦归结为共享库不像我想象的那样“共享”,并试图使用一个进程的句柄来索引一个尚未在第二个进程中初始化的表。取决于事情的启动方式,可能会或可能不会导致第三个进程中的重要数据被丢弃。
任何未定义的行为。即:需要数百页来解释输出更改的每个可能来源。尝试调试以查找发生更改的位置,或阅读一些 C++ 规范。