未初始化的变量如何获得随机值?

时间:2013-06-20 14:43:00

标签: c undefined-behavior initialization

假设我声明了一个变量x并保持未初始化状态。我继续打印它的价值。我看到一些垃圾。

它来自哪里?为什么它不用于生成随机数?我的意思是代替使用伪随机生成器。

4 个答案:

答案 0 :(得分:8)

“随机”值就是该位置内存中的内容。当记忆被释放时,记忆通常不会被删除/归零,因此无论记忆被覆盖都会留下来。

答案 1 :(得分:1)

垃圾可能来自两个地方:

  • 当动态RAM上电时,单元保持在任意状态,直到初始化为止;这是内存的大多数硬件实现的属性
  • 当您的程序运行时,它会留下以前使用但不再在范围内的变量值。此属性可能用于攻击:分析程序遗留的垃圾可能会向插件或您使用的其他库的不道德作者提供信息。

答案 2 :(得分:0)

未初始化变量的值是在将相应的内存区域分配给此变量之前存在的值。大多数情况下,它是不可预测的,并取决于此内存区域之前发生的任何事情。

实际上这有时用作附加熵来生成伪随机数。几年前,Debian开发人员认为未初始化的变量是OpenSSL中的一个错误并将其设置为零。然后生成的密钥变得有些猜测,现在每个Debian用户都必须在他们的机器上安装一长串黑名单。

答案 3 :(得分:0)

答案简短?这取决于您的编译器 - 但不要这样做。

答案很长:
访问未初始化的POD(普通旧数据,例如int)类型的值会调用未定义的行为,这意味着在这种情况下,C标准不会对符合要求的实现提出任何要求。因此,允许编译器发出启动nethack,格式化硬盘驱动器或根本不执行任何操作的机器代码,同时仍符合C标准 - 只要它能证明未定义的行为发生在您的任何地方程序

(另请阅读:What Every C Programmer Should Know About Undefined Behavior

那么,实际上(可能)会发生什么?
在大多数现代编译器没有启用优化的情况下,编译器只需在堆栈(或寄存器)上为变量分配一个插槽,然后在被询问之前访问该位置的任何内容。结果似乎是"随机记忆",尽管实际上是it's not very random at all

如果我启用优化会发生什么?
然后,如果您在更高的优化级别上编译代码(或者编译器已更新并且现在更积极地进行优化),则所有投注均已关闭。例如,编译器可以删除涉及x的任何调用,将x分配到与其他变量相同的位置(认为x不可能被使用,因为它不是{&#39}。 t初始化),或any other combination of strange effects

换句话说,当您访问未初始化的变量时,您的程序可以开始在控件之外执行任何。不要这样做 - 这里是龙。