"Random"确定性C++程序的输出。可能的原因?

"Random" output from a determinstic C++ program. Possible causes?

本文关键字:输出 Random 确定性 C++ 程序      更新时间:2023-10-16

我在64位Windows PC上使用Microsoft Visual Studio Community 2015,版本 14.xxx。

程序读取一个文本文件,其中每行都是桥牌交易(四名玩家每人有 13 张牌)。 该文件是由可靠的第三方程序生成的,但我还是验证了每笔交易,并且每个输入行都通过了验证。

然后,我根据点数、花色长度等变量将"相似"交易分组到类(箱)中。 这是使用字符串流和我的 Bin 结构映射的标准文本处理。 对于给定的输入文件,这是完全确定的。

大约 3/4 的时间我得到相同的输出,例如 23 个可能的箱 - 正如预期的那样,跨箱的交易频率加起来就是输入交易的数量。 但剩余的输出可能有 6 到 50 个箱(具有正确的频率总数)。

这种随机性可能从何而来? 我使用所有变量的默认初始化,因此,即使这是错误的,它也应该在给定文件的程序运行中保持一致。 例如

std::string line;  //  Raw data on a deal.
std::vector<std::string> parsed_deal;
std::map<std::string, struct Bin> m_bin;
std::stringstream ss_bin[MAX_BINS]; 

默认初始化并不意味着每次运行程序时,所有变量都将以完全相同的方式初始化。 特别是,默认初始化意味着在某些情况下未初始化。 例子包括未初始化的基本类型(intfloat、指针、数组等)(例如 auto未初始化为零的变量),以及实际上未由构造函数初始化的类类型的此类成员。 访问未初始化变量的值(更不用说取消引用它,如果它是一个指针)会给出未定义的行为。

当然,未定义行为还有其他原因(从数组末尾掉落、骚扰指针、在同一指针上调用运算符delete两次、在 malloc() 返回的指针上调用运算符delete)。

如果行为是未定义的,那么"非确定性"行为是一种可能的结果。 例如,当一个变量被定义但未初始化时,它的值可能基于之前在该物理/逻辑内存位置中发生的任何情况。 因此,访问其值的结果将取决于以前使用该内存的其他代码(在您的程序中,在您的操作系统中,甚至在另一个进程中),以及该内存在程序访问它之前如何/是否被覆盖。