下面的情况,我有一个结构包含指向整数变量的指针,如下所示:
struct Structure[] = {
{ &Var[0], &Var[1] },
{ &Var[2], &Var[3] }
};
事情是:Var
在第一次填充此结构时未初始化。 (如:NULL
)
不久之后(第一次通过),变量Var
将被初始化,引用将相应更新。
我认为这没有理由发生故障,但我希望你的专业知识。 将无效内存(带数组下标)的引用放入这样的数组中是否合法?或者我是否需要针对这种情况采用不同的方法?
在第一次初始化之前,我才会访问这些变量的内容。
非常感谢。
编辑:
为了未来读者的利益:Var
是一个全局指针变量,在开始时初始化为NULL。初始化使用new
将其转换为数组。
答案 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)
回答具体问题(忘记示例代码):是的,你可以引用未初始化的内存,你根本无法取消引用它并期望定义的行为。