没有访问它就引用未初始化的内存是合法的吗?

时间:2013-08-05 15:01:38

标签: c++ variables memory

下面的情况,我有一个结构包含指向整数变量的指针,如下所示:

struct Structure[] = { 
    { &Var[0], &Var[1] },
    { &Var[2], &Var[3] }
};

事情是:Var在第一次填充此结构时未初始化。 (如:NULL) 不久之后(第一次通过),变量Var将被初始化,引用将相应更新。

我认为这没有理由发生故障,但我希望你的专业知识。 将无效内存(带数组下标)的引用放入这样的数组中是否合法?或者我是否需要针对这种情况采用不同的方法?

在第一次初始化之前,我才会访问这些变量的内容。

非常感谢。

编辑: 为了未来读者的利益:Var是一个全局指针变量,在开始时初始化为NULL。初始化使用new将其转换为数组。

3 个答案:

答案 0 :(得分:8)

我假设Var是一个指针对象,它的当前值是一个空指针。您的陈述暗示了这一点:

  第一次填充此结构时,

Var未初始化。 (如:NULL

我还假设Var未在块范围内定义。如果它在块作用域中定义,并且您尚未初始化它或为其赋值,则其值为garbage,不一定是空指针值,并且任何引用其值的尝试都具有未定义的行为。

行为未定义。

如果Var == NULL,则&Var[N]有未定义的行为。

根据定义,

arr[index]等同于*(arr + index),因此&Var[N]相当于&(*(Var + N))。指针算术的行为是根据指针所指向的数组对象的元素(将单个对象视为单元素数组)和空指针指向任何内容来定义的。

一个题外话:

C明确表示&*x评估为x&[x[i])评估为x+i; C ++没有这样说,因此&的操作数必须有效。 C ++有一个特殊的情况,即添加0,即使对于空指针也很明确(C没有这种特殊情况)。但是&Var[0]在C和C ++中仍然无效,但出于不同的原因。在C中,它等同于Var + 0,但是向空指针添加0具有未定义的行为。在C ++中,它的不是等同于Var + 0;相反,它相当于&(*(Var + 0)); Var + 0是一个空指针,取消引用它有未定义的行为。)

离题结束。

是的,只计算一个无效的地址有未定义的行为,即使它从未被解除引用。

以下是2011年ISO C ++标准5.7 [expr.add]第5段的相关文字;特别注意最后:

  

添加或减去具有整数类型的表达式时   从指针开始,结果具有指针操作数的类型。如果   指针操作数指向数组对象的元素和数组   足够大,结果指向一个偏离的元素   原始元素使得下标的差异   结果和原始数组元素等于整数表达式。   换句话说,如果表达式P指向一个的第i个元素   数组对象,表达式(P)+ N(等效地,N +(P))和(P)-N   (其中N具有值n)分别指向第i + n和i    - 数组对象的第n个元素,只要它们存在即可。而且,如果   表达式P指向数组对象的最后一个元素,即   表达式(P)+1指向数组对象的最后一个元素,   如果表达式Q指向一个数组的最后一个元素   对象,表达式(Q)-1指向数组的最后一个元素   宾语。如果指针操作数和结果都指向元素   相同的数组对象,或一个超过数组的最后一个元素   对象,评估不得产生溢出;否则,   行为未定义。

答案 1 :(得分:2)

由于您在第一次传递之后才使用这些值,所以请执行正确的操作并将结构的指针初始化为null。然后在知道它们时输入正确的值。如果采取这种方法,你的“合法”问题就会消失!

答案 2 :(得分:0)

回答具体问题(忘记示例代码):是的,你可以引用未初始化的内存,你根本无法取消引用它并期望定义的行为。