6

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

它从何而来?另外为什么不使用它来生成随机数?我的意思是不要使用伪随机生成器。

4

4 回答 4

8

“随机”值就是那个位置的内存中留下的东西。内存在被释放时通常不会被擦除/归零,所以那里的任何东西都会一直存在直到它被覆盖。

于 2013-06-20T14:44:47.657 回答
1

垃圾可能来自两个地方:

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

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

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

于 2013-06-20T14:52:46.367 回答
0

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

长答案:
访问未初始化的 POD(普通旧数据,例如int)类型的值会调用未定义的行为,这意味着 C 标准在这种情况下对符合要求的实现没有任何要求。因此,允许编译器发出启动nethack、格式化硬盘驱动器或什么都不做的机器代码,同时仍然符合 C 标准——只要它可以证明未定义的行为发生在程序中的任何位置。

(另请阅读:每个 C 程序员都应该知道的关于未定义行为的知识

那么,实际上(可能)会发生什么?
在大多数没有启用优化的现代编译器上,编译器将简单地将堆栈(或寄存器)上的一个插槽分配给变量,然后在被询问之前访问该位置的任何内容。结果似乎是“随机记忆”,但实际上它根本不是随机的

如果我启用优化会发生什么?
如果您然后在更高的优化级别上编译您的代码(或者编译器已更新并且现在更积极地优化),那么所有的赌注都没有了。例如,编译器可能会删除任何涉及 的调用x,分配x到与其他变量相同的位置(认为x不可能使用,因为它尚未初始化),或任何其他奇怪效果的组合

换句话说,当你访问那个未初始化的变量时,你的程序就可以开始做任何你无法控制的事情。不要这样做——这里是龙。

于 2017-07-31T20:27:42.147 回答