C++ 引用未初始化的内存而不访问它是否合法?
在以下情况下,我有一个包含指向整数变量指针的结构,如下所示:C++ 引用未初始化的内存而不访问它是否合法?,c++,variables,memory,C++,Variables,Memory,在以下情况下,我有一个包含指向整数变量指针的结构,如下所示: struct Structure[] = { { &Var[0], &Var[1] }, { &Var[2], &Var[3] } }; 问题是:Var在第一次填充此结构时未初始化。(如:NULL) 不久之后(第一次通过时),变量Var将被初始化,引用将相应地更新 我看不出有什么原因会出现故障,但我希望你能提供这方面的专业知识。 将对无效内存(带有数组下标)的引用放入这样的数组中是否
struct Structure[] = {
{ &Var[0], &Var[1] },
{ &Var[2], &Var[3] }
};
问题是:Var
在第一次填充此结构时未初始化。(如:NULL
)
不久之后(第一次通过时),变量Var
将被初始化,引用将相应地更新
我看不出有什么原因会出现故障,但我希望你能提供这方面的专业知识。
将对无效内存(带有数组下标)的引用放入这样的数组中是否合法?还是我需要一种不同的方法来应对这种情况 在第一次初始化之前,我不会访问这些变量的内容 多谢各位 编辑:
为了方便将来的读者:
Var
是一个全局指针变量,在开始时初始化为NULL。初始化通过使用new
将其转换为数组。我假设Var
是指针对象,其当前值是空指针。你的声明暗示了这一点:
第一次填充此结构时,Var
未初始化。(如:NULL
)
我还假设Var
未在块范围内定义。如果它是在块范围中定义的,并且您没有初始化它或为它分配值,那么它的值是垃圾,不一定是空指针值,并且任何引用它的值的尝试都有未定义的行为
该行为未定义
如果Var==NULL
,则&Var[N]
具有未定义的行为
arr[index]
根据定义相当于*(arr+index)
,因此&Var[N]
相当于&(*(Var+N))
。指针算法的行为是根据数组对象的元素定义的,指针指向数组对象的元素(将单个对象视为一个元素数组),空指针不指向任何对象
离题:
C明确地表示<代码>和*x/Cux>被评估为<代码> [x[i])//> >被评估为<代码> x+i ;C++不表示这一点,因此<代码>和<代码>的操作数必须有效。C++有一个特殊的情况,用于添加<代码> 0 < /C> >,即使对于空指针(C没有特殊情况),它也被定义得很好。但是<代码>和var(0)在C和C++中,仍然无效,但由于不同的原因,在C中,它等同于代码> VAR+0 < /C>,但是添加一个空指针的代码> 0 >代码有不明确的行为。在C++中,它不等同于代码> var + 0 < /C>;而是等价于<代码>和(*(var +0))。;
Var+0
是一个空指针,取消引用它有未定义的行为。)
离题结束
是的,仅仅计算一个无效地址就有未定义的行为,即使它从未被解除引用
下面是2011个ISO C++标准的相关文本,5.7 [ Exp.Ad]第5段;特别注意的是:
当对具有整数类型的表达式进行加法或减法运算时
对于指针,结果具有指针操作数的类型。如果
指针操作数指向数组对象的元素,数组
如果足够大,则结果将指向与
原始元素,例如
结果和原始数组元素等于积分表达式。
换句话说,如果表达式P指向
数组对象,表达式(P)+N(等价地,N+(P))和(P)-N
(其中N的值为N)分别指向i+N和i
− 数组对象的第n个元素,前提是它们存在。此外,如果
表达式P指向数组对象的最后一个元素
表达式(P)+1点超过数组对象的最后一个元素,
如果表达式Q指向数组最后一个元素的前面一个
对象,表达式(Q)-1指向数组的最后一个元素
如果指针操作数和结果都指向元素
同一数组对象的,或超过数组最后一个元素的
对象,则评估不应产生溢出;否则
行为是未定义的
因为在第一次传递之后才使用这些值,所以请做正确的事情,并将结构的指针初始化为null。然后在您知道这些值的情况下将其放入。如果采用这种方法,您的“是否合法”问题就会消失!回答特定问题(忘记示例代码):是的,您可以引用未初始化的内存,但您不能取消引用它并期望定义的行为。我可以合理地确定答案是否定的,一些优化器会破坏您的代码。“或者我需要一种不同的方法来处理这种情况吗?”嗯,也许,初始化变量?
Var
是引用还是指针?什么是未初始化的,Var
或Var[0]
?如果Var
被初始化为指向“未初始化的内存区域”那么你的代码就可以了。如果Var
是一个未初始化的指针,那么它在每个方向上都是UB。如果它是一个类型为T
的数组,具有未初始化的内容,那么这就是定义的行为,只要你不读取存储在结构中(或Var
中)的地址上的内容直到上述位置的存储本身被初始化。没有更多关于Var类型的信息,这是我能提供的最深刻的评论。你能提供禁止对空指针进行算术运算的参考吗?或者我误解了你的意思吗?@MarkB这与法律定义有关NULL
的定义。如果NULL
被定义为((void*)0)
(C中合法,C++中非法),那么对其进行任何运算都是非法的。(显然,如果NULL
被定义为<