在 C ++ Primer Plus(第6版),第73页中,它指出:
如果您没有初始化函数内定义的变量, 变量的值是 indeterminate 。这意味着价值 无论发生什么事情都要坐在那个记忆位置之前 创建该变量。
这是否意味着我可以使用未初始化的变量来获取程序中该点的内存位置数据?如果为true,是否存在此属性有用的任何实例?
答案 0 :(得分:4)
标准的引用措辞如下(§8.5[dcl.init] ):
如果没有为对象指定初始化程序,则默认初始化该对象;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值。
这本书对该地区以前可用的价值有点误导。这通常是正确的,但不一定。
重要的一点是,访问此类对象的值会导致未定义的行为。访问对象的值正式称为左值到右值的转换,它说明了这一点(§4.1[conv.lval] ):
如果glvalue引用的对象不是T类型的对象,并且不是从T派生的类型的对象,或者如果对象未初始化,则需要此转换的程序具有未定义的行为。
仅当表达式中的运算符需要rvalue操作数时才会发生这种情况,通常就是这种情况。但是,一元&
运算符需要左值操作数,因此不应用左值到右值的转换。这意味着获取未初始化变量的地址是可以的。这具有逻辑意义,因为对象存在且具有有效地址,所以它不会被初始化。获取地址不需要访问对象的值。
你为什么要这样做?很难想到一个具体的例子,因为这个想法非常广泛,因为我们不会经常将我们的变量保留为未初始化(如果有的话)。如果您需要在为其分配值之前存储对象的地址,则需要执行此操作。您可以稍后通过该指针访问该对象(一旦分配给它)。实际上,您可以通过指针分配给它。
答案 1 :(得分:1)
虽然标准有效禁止使用未初始化变量的值,但您通常无论如何都能读取它,并且它通常确实包含上次存储在该位置的任何值。
但是,此信息无论如何都无用。由于您的程序始终在其自己的私有虚拟地址空间中运行,因此您可能阅读的任何内容都是由您自己的程序编写的。也就是说,无论如何你已经掌握了这些信息,你可以用更安全的方式传递信息。如果您在函数中使用未初始化的变量,则尤其如此:您将能够看到的那种方式是通过您之前调用的某个函数写入局部变量的信息。
您可能能够找到标准C库和您使用的其他库的一些内部,因为它们的代码在您的地址空间中运行。但是大多数信息无论如何都不会存储在堆栈中,因此您需要从未初始化的变量读取其他内存位置的数据。你需要取消引用你不拥有的东西的指针,这实际上是未定义的行为。如果你试试这个,你很可能会遇到段错误。
所以,是的,它可能,但......