c - 二维数组索引 - 未定义的行为?

标签 c arrays multidimensional-array undefined-behavior

我最近研究了一些代码来执行一些有问题的二维数组索引操作。以下面的代码示例为例:

int a[5][5];
a[0][20] = 3;
a[-2][15] = 4;
a[5][-3] = 5;

上述索引操作是否受制于未定义的行为?

最佳答案

这是未定义的行为,原因如下。

多维数组访问可以分解为一系列的一维数组访问。换句话说,表达式 a[i][j]可以认为是 (a[i])[j] .引用 C11 §6.5.2.1/2:

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

这意味着以上内容与 *(*(a + i) + j) 相同.按照 C11 §6.5.6/8 关于整数和指针的加法(强调我的):

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

换句话说,如果a[i]不是有效索引,行为立即未定义,即使“直观地”a[i][j]似乎在界内。

所以,在第一种情况下,a[0]有效,但以下 [20]不是,因为 a[0] 的类型是int[5] .因此,索引 20 超出范围。

在第二种情况下,a[-1]已经出界,因此已经是 UB。

然而,在最后一种情况下,表达式 a[5]指向数组最后一个元素之后的一个,根据 §6.5.6/8 有效:

... if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object ...

但是,在同一段的后面:

If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

所以,虽然 a[5]是一个有效的指针,取消引用它会导致未定义的行为,这是由最终 [-3] 引起的索引(这也是越界的,因此是 UB)。

关于c - 二维数组索引 - 未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25139579/

相关文章:

php - 对于MySQL查询中的每个结果,推送到数组(复杂)

c - 为什么 2nd scanf 在我的程序中不起作用?

php - 如何使用 PHP 和 C 将大图保存在内存中?

c - 您如何告诉 Frama-C 和 Eva 入口点的参数被假定为有效?

c - 如何计算数组C中的值被使用了多少次?

javascript - 使用数组和 for 循环获取

PHP-循环遍历多维数组并在找到键时减少数组

使用 C 中的数组计算直角三角形的斜边

c - 使用 GTK+2 和 Cairo 实现非常简单、流畅的动画

c++ - 如何在 C++ 中使用 for 循环递增两个不同的值