我知道未初始化的局部变量是未定义的行为(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);
    }
}

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


当前回答

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

其他回答

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

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

A_Function_that_use_a_lot_the_Stack();
updateEffect();

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

未定义的行为意味着编译器的作者可以自由地忽略这个问题,因为无论发生什么,程序员都没有权利抱怨。

理论上,当进入UB域时,任何事情都可能发生(包括守护进程从你鼻子上飞出去),通常意味着编译器作者不会关心,对于局部变量,其值将是当时堆栈内存中的任何值。

这也意味着内容通常是“奇怪的”,但是是固定的,或者是稍微随机的,或者是可变的,但是有一个清晰的模式(例如,在每次迭代中增加值)。

当然,你不能指望它是一个不错的随机生成器。

There are certain situations in which uninitialized memory may be safely read using type "unsigned char*" [e.g. a buffer returned from malloc]. Code may read such memory without having to worry about the compiler throwing causality out the window, and there are times when it may be more efficient to have code be prepared for anything memory might contain than to ensure that uninitialized data won't be read (a commonplace example of this would be using memcpy on partially-initialized buffer rather than discretely copying all of the elements that contain meaningful data).

然而,即使在这种情况下,人们也应该始终假设,如果字节的任何组合特别烦人,那么读取它总是会产生字节的模式(如果某个模式在生产中是烦人的,但在开发中不是,那么这种模式直到代码进入生产中才会出现)。

Reading uninitialized memory might be useful as part of a random-generation strategy in an embedded system where one can be sure the memory has never been written with substantially-non-random content since the last time the system was powered on, and if the manufacturing process used for the memory causes its power-on state to vary in semi-random fashion. Code should work even if all devices always yield the same data, but in cases where e.g. a group of nodes each need to select arbitrary unique IDs as quickly as possible, having a "not very random" generator which gives half the nodes the same initial ID might be better than not having any initial source of randomness at all.

正如其他人所说,这将是快速的,但不是随机的。

大多数编译器对局部变量所做的是在堆栈上为它们抓取一些空间,而不是费心将其设置为任何东西(标准说它们不需要这样做,所以为什么要减慢生成的代码呢?)

在这种情况下,你将得到的值将取决于之前在堆栈上的内容——如果你在这个函数之前调用一个有100个局部char变量设置为'Q'的函数,然后在该函数返回后调用你的函数,那么你可能会发现你的“随机”值表现得就像你已经将memset()它们全部设置为'Q'。

重要的是,你的例子函数尝试使用这个,这些值不会改变每次你读取他们,他们将是相同的每一次。所以你会得到100颗星星都设置成相同的颜色和能见度。

而且,没有什么说编译器不应该初始化这些值——所以将来的编译器可能会这样做。

总的来说:坏主意,不要做。 (就像很多“聪明的”代码级优化一样……)