我知道未初始化的局部变量是未定义的行为(UB),而且值可能有陷阱表示,这可能会影响进一步的操作,但有时我想使用随机数仅为视觉表示,而不会在程序的其他部分进一步使用它们,例如,在视觉效果中设置随机颜色的东西,例如:

void updateEffect(){
    for(int i=0;i<1000;i++){
        int r;
        int g;
        int b;
        star[i].setColor(r%255,g%255,b%255);
        bool isVisible;
        star[i].setVisible(isVisible);
    }
}

比那么快吗

void updateEffect(){
    for(int i=0;i<1000;i++){
        star[i].setColor(rand()%255,rand()%255,rand()%255);
        star[i].setVisible(rand()%2==0?true:false);
    }
}

也比其他随机数生成器快吗?


当前回答

您的特定代码示例可能无法实现您所期望的功能。虽然从技术上讲,循环的每次迭代都为r、g和b值重新创建局部变量,但实际上它们在堆栈上是完全相同的内存空间。因此,它不会在每次迭代中重新随机化,你最终将为1000种颜色中的每一种分配相同的3个值,而不管r、g和b最初是多么随机。

事实上,如果它确实有效,我会非常好奇是什么让它重新随机化。我唯一能想到的就是在这个堆栈上有一个交错的中断,这是不太可能的。也许内部优化将它们作为寄存器变量,而不是真正的内存位置,在循环中寄存器被重用,这也会奏效,特别是如果设置可见性函数特别需要寄存器的话。不过,这远不是随机的。

其他回答

真的不好!坏习惯,坏结果。 考虑:

A_Function_that_use_a_lot_the_Stack();
updateEffect();

如果函数A_Function_that_use_a_lot_the_Stack()总是进行相同的初始化,则堆栈上保留相同的数据。这些数据就是我们调用updateEffect()得到的:总是相同的值!

你需要对“随机”有一个定义。 一个合理的定义是,你得到的值应该没有什么相关性。这是可以测量的。以一种可控的、可复制的方式实现这一点也并非易事。所以未定义的行为肯定不是你要找的。

您的特定代码示例可能无法实现您所期望的功能。虽然从技术上讲,循环的每次迭代都为r、g和b值重新创建局部变量,但实际上它们在堆栈上是完全相同的内存空间。因此,它不会在每次迭代中重新随机化,你最终将为1000种颜色中的每一种分配相同的3个值,而不管r、g和b最初是多么随机。

事实上,如果它确实有效,我会非常好奇是什么让它重新随机化。我唯一能想到的就是在这个堆栈上有一个交错的中断,这是不太可能的。也许内部优化将它们作为寄存器变量,而不是真正的内存位置,在循环中寄存器被重用,这也会奏效,特别是如果设置可见性函数特别需要寄存器的话。不过,这远不是随机的。

好问题!

未定义并不意味着它是随机的。考虑一下,在全局未初始化变量中获得的值是由系统或您的/其他应用程序运行时遗留在那里的。根据您的系统对不再使用的内存的处理和/或系统和应用程序生成的值类型,您可能会得到:

总是一样的。 成为一小部分价值观中的一员。 获取一个或多个小范围内的值。 在16/32/64位系统的指针上看到许多可以被2/4/8整除的值 ...

您将得到的值完全取决于系统和/或应用程序留下的非随机值。因此,确实会有一些噪音(除非您的系统删除不再使用的内存),但您将从中提取的值池绝不是随机的。

对于局部变量,情况会变得更糟,因为它们直接来自您自己程序的堆栈。在执行其他代码期间,您的程序很有可能实际编写这些堆栈位置。我估计在这种情况下运气的机会非常低,而你所做的“随机”代码更改将尝试这种运气。

阅读随机性。正如你所看到的,随机性是一种非常特殊且难以获得的属性。一个常见的错误是,如果你只是采取一些难以跟踪的东西(比如你的建议),你会得到一个随机的值。

由于安全原因,必须清理分配给程序的新内存,否则信息可能会被使用,密码可能会从一个应用程序泄漏到另一个应用程序。只有在重用内存时,才会得到不同于0的值。很有可能,在堆栈上,前一个值是固定的,因为前一个内存的使用是固定的。