#include <iostream>
#include <random>
using namespace std;
class myclass
{
private:
static bool randomBit()
{
std::random_device rd; // Obtain a random seed number from hardware
std::mt19937 gen(rd()); // Initialize and seed the generator <---- CRASH!!
uniform_int_distribution<> distr(0, 1); // Define the distribution range
return distr(gen);
}
myclass::myclass() = delete; // Disallow creating an instance of this object
public:
static bool generateRandomBit()
{
return randomBit();
}
};
int main()
{
cout<<myclass::generateRandomBit()<<endl;
return 0;
}
这将编译并运行MSVC,而不会出现问题。它使用gcc
编译时没有错误,但是mt19937 gen(rd());
行导致程序崩溃,并显示以下消息:
“ myprog.exe停止工作
一个问题导致程序无法正常运行。 Windows将关闭该程序,并在解决方案可用时通知您。“
有什么想法吗?
gcc命令:g++ mycode.cpp -fpermissive -s -o myprog.exe
更新:
将-O2
添加到编译命令可以使程序运行,尽管这样做是不正确的。 “随机”功能不再是随机的。它总是返回1。例如,使用以下“主要”代码进行测试...
int main()
{
int a[2] {0, 0};
for (int i = 0; i < 1000; i++) {
a[myclass::generateRandomBit()]++;
}
cout<<"<"<<a[0]<<", "<<a[1]<<">"<<endl;
return 0;
}
...产生以下输出:<0, 1000>
答案 0 :(得分:1)
看来这是nuwen发行版的问题。 16.0和16.1版本都在std :: random_device构造函数上或在值生成期间生成某种类型的Undefined Behavior,有时会导致静默崩溃,但是很难创建一个简约的示例。
当编译的优化级别大于0时,崩溃似乎消失了。 我不会依赖它,因为最有可能的UB仍然存在于某个地方,并且程序可能在最意想不到的地方崩溃。
版本16.0使用GCC 8.1.0,版本16.1使用GCC 8.2.0。 从https://sourceforge.net/projects/mingw-w64/下载的MinGW(也使用8.1.0版本),我无法重现此错误。
此外,请注意,MinGW上的std :: random_device不会提供随机数-它是确定性的,始终提供相同的值。不幸的是,标准允许这样做,我认为这是个大问题。
如果每次运行只需要不同的值,请考虑使用其他非随机源作为种子,例如C库中的时间。如果确实需要不确定的值,则可以使用nuwen发行版随附的boost :: random :: random_device(与std :: random_device相同的接口)。虽然它不是仅标头,所以您需要添加额外的链接:
g ++ foo.cpp -lboost_random -lboost_system