Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果不使用';你不用它吗?_C++_C_Arrays_Undefined Behavior - Fatal编程技术网

C++ 如果不使用';你不用它吗?

C++ 如果不使用';你不用它吗?,c++,c,arrays,undefined-behavior,C++,C,Arrays,Undefined Behavior,在我正在编写的算法中,我可以有以下内容(当然是简化的) 当用于填充b的索引溢出时,我从不使用b的值。代码仍然不正确吗?是否必须进行显式边界检查?无论您是否使用b,此代码都有未定义的行为。为什么?因为a[3]在定义上等同于*(a+3)。这里引用了标准中的一句话,它证明了*(a+3)本身是未定义的,无论该值是存储的、使用的还是单独保留的 当一个表达式具有整数 类型被添加到或从中减去 指针,结果的类型为 指针操作数。如果指针 操作数指向 数组对象,并且数组很大 够了,结果指向一个 图元相对于原始图元的

在我正在编写的算法中,我可以有以下内容(当然是简化的)


当用于填充
b
的索引溢出时,我从不使用b的值。代码仍然不正确吗?是否必须进行显式边界检查?

无论您是否使用
b
,此代码都有未定义的行为。为什么?因为
a[3]
在定义上等同于
*(a+3)
。这里引用了标准中的一句话,它证明了
*(a+3)
本身是未定义的,无论该值是存储的、使用的还是单独保留的

当一个表达式具有整数 类型被添加到或从中减去 指针,结果的类型为 指针操作数。如果指针 操作数指向 数组对象,并且数组很大 够了,结果指向一个 图元相对于原始图元的偏移量 元素的差异 结果和的下标 原始数组元素等于 积分表达式。换句话说,, 如果表达式P指向第i个 数组对象的元素 表达式(P)+N(等效), N+(P))和(P)-N(其中N具有 值n)分别指向 i+n-th和i−第n个元素 数组对象,前提是它们存在。 此外,如果表达式P指向 到数组的最后一个元素 对象,表达式(P)+1点 超过数组最后一个元素一个 对象,如果表达式Q指向 一个数组的最后一个元素 对象,表达式(Q)-1指向 数组对象的最后一个元素。 如果指针操作数和 结果指向相同的元素 数组对象,或超过最后一个 数组对象的元素 评估不应产生任何结果 过流;否则,该行为是错误的 未定义

通过将值复制到
b
中,可以使用该值


更具体地说,不允许取消引用
(a+3)
,因为表达式
(a+3)
不是有效的指针。。。表达式
a[3]
相当于
*(a+3)
(其中
a
已衰减为指针表达式)。

是的,读取不存在的
a[3]
是错误的


使用
b
也将是错误的,但为时已晚。

仍然是错误的,仍然是未定义的行为。做边界检查

int b = *(a + 3); // dereferencing beyond the array bound.

读取[3]已导致未定义的行为。由于未定义的行为从不受本地限制,这可能已经导致您的硬盘驱动器被格式化,或者您的计算机变成一个巨大的食肉僵尸

实际上,它通常只会起作用。但是很容易将数组的结尾标记为映射内存区域的结尾,因此访问一个元素会导致分段错误。对于堆栈上的
int
数组和大多数堆实现来说,情况肯定不是这样,但您不应该依赖它


(获取
&a[3]
的地址是否也是未定义的行为。)

仍然是不正确的,因为您访问越界内存位置以获取值
a[3]
,并将其存储在变量
b

您从未使用
b
这一事实可能意味着编译器优化了该行代码,因此您可能永远不会看到该行代码的任何不利影响


但是,编译器不需要这样做,代码本身仍然有未定义的行为。

b
只是一个int,使用它有什么害处?当然,它有不确定的值,但使用它并不是内存不正确…@Kerrek SB
int
s允许有补漏白值(在某些实现中也是如此)。@Kerrek-您无法读取不确定的值,它可能会补漏白。这里也没关系,因为在开始阅读
b
@James:trapping值是什么,它如何影响程序流?实际的冲突发生在不确定值发挥作用之前。这是一个数组边界冲突,即使您知道数组后面有有效内存(例如,如果它来自
malloc
或结构),如果该位置的数据不是
int[3]
@Downvoter类型的数组的一部分,这也是一个别名冲突:如果您能告诉我如何改进这个答案,我会很高兴!显然有人不同意并否决了几个答案。:-)@Kerrek:Woops,将其理解为“代码是否仍然正确?”“或数组对象的最后一个元素后一个元素,求值不应产生过流”-->如果索引等于数组的大小,这是否意味着代码是正确的?@static\u rtti:是的,但仅当您使用指针算术(
(a+3)
)并且您不应取消引用您得到的指针(这会自动发生在
a[3]
中)。为什么
&a[3]
的有效性有争议?它与明确允许的
a+3
相同。或者,你是不是说C++中的冗余代码<代码>和代码>最初是一个“引用”?@ R:如果你遵循这个链接,你可以自己读到这个争论。R..:我认为这是一个部分,另一个是Irc,在C++中,指向没有被语言分配的内存区域的指针是无效的。如果我们至少谈论C,这根本不应该引起很大争议&[3]是完全合法的,因为在[]操作数上使用&并不表示任何含义:“类似地,如果操作数是[]运算符的结果,则不会计算[]所隐含的&运算符或一元数*,结果就好像删除了&运算符,将[]运算符更改为+运算符“”,并将右值
a[3] 
..”没有任何意义。
a[3]
不是指针或数组;它具有类型
int
.R.:…这是
*(a+3)的结果
int b = *(a + 3); // dereferencing beyond the array bound.