二维数组索引 - 未定义的行为? [英] 2D Array indexing - undefined behavior?

查看:16
本文介绍了二维数组索引 - 未定义的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've recently got into some pieces of code doing some questionable 2D arrays indexing operations. Considering as an example the following code sample:

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

上面的索引操作是否受到未定义行为的影响?

Are the indexing operations above subject to undefined behavior?

推荐答案

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

It's undefined behavior, and here's why.

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

Multidimensional array access can be broken down into a series of single-dimensional array accesses. In other words, the expression a[i][j] can be thought of as (a[i])[j]. Quoting C11 §6.5.2.1/2:

下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2))).

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

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

This means the above is identical to *(*(a + i) + j). Following C11 §6.5.6/8 regarding addition of an integer and pointer (emphasis mine):

如果两个指针操作数和结果指向同一个数组对象的元素,或者最后一个数组对象的元素,评估不应产生溢出;否则,行为未定义.

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]似乎在界内.

In other words, if a[i] is not a valid index, the behavior is immediately undefined, even if "intuitively" a[i][j] seems in-bounds.

所以,在第一种情况下,a[0] 是有效的,但是下面的 [20] 不是,因为 a[0] 的类型]int[5].因此,索引 20 越界.

So, in the first case, a[0] is valid, but the following [20] is not, because the type of a[0] is int[5]. Therefore, index 20 is out of bounds.

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

In the second case, a[-1] is already out-of-bounds, thus already UB.

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

In the last case, however, the expression a[5] points to one past the last element of the array, which is valid as per §6.5.6/8:

... 如果表达式 P 指向数组对象的最后一个元素,则表达式 (P)+1 指向数组最后一个元素的后面对象...

... 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 ...

但是,在同一段落的后面:

However, later in that same paragraph:

如果结果指向数组对象的最后一个元素,则不应将其用作被评估的一元 * 运算符的操作数.

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).

So, while a[5] is a valid pointer, dereferencing it will cause undefined behavior, which is caused by the final [-3] indexing (which, is also out-of-bounds, therefore UB).

这篇关于二维数组索引 - 未定义的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆