首页 >后端开发 >C++ >使用指针算术访问超出其范围的 2D 数组元素是否会导致未定义的行为?

使用指针算术访问超出其范围的 2D 数组元素是否会导致未定义的行为?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-31 12:35:09516浏览

Does Accessing a 2D Array Element Using Pointer Arithmetic Beyond Its Bounds Result in Undefined Behavior?

二维数组可以被视为连接的一维数组吗?

考虑以下代码片段:

int a[25][80];
a[0][1234] = 56;
int* p = &a[0][0];
p[1234] = 56;

问题:代码是否访问数组超出其范围,导致未定义的行为?

答案:是的,第 2 行和第 4 行都表现出未定义的行为。

在 C 中,数组索引本质上是指针算术。当访问 a[i][j] 时,编译器有效地将其转换为 *(a[i] j)。类似地,p[i] 引用 *(p i)。

在这种情况下,数组 a 的维度为 25 x 80。数组的第一行 a[0] 包含 80 个元素(范围为a[0][0] 到 a[0][79]) 并分配在连续的内存位置。

通过访问a[0][1234],代码尝试访问第一行中索引 1234 处的元素,尽管 a[0] 仅包含 [0, 79] 范围内的元素。这是越界并触发未定义的行为。

相同的逻辑适用于第 4 行。虽然 p 指向 a[0] 的第一个元素,但数组的尺寸仍然为 25 x 80。访问 p[ 1234] 本质上是一个越界指针算术运算,再次导致未定义的行为。

此外,正如 Language Lawyer 在注释中,使用 constexpr 的类似代码片段将无法编译,因为编译器在常量表达式中检测到此类未定义的行为:

constexpr int f(const int (&a)[2][3])
{
    auto p = &a[0][0];
    return p[3];
}

int main()
{
    constexpr int a[2][3] = { 1, 2, 3, 4, 5, 6, };
    constexpr int i = f(a);
}

这可以正确编译,因为使用 constexpr 访问 p[3] 会触发编译器检测未定义的行为并抛出错误。

以上是使用指针算术访问超出其范围的 2D 数组元素是否会导致未定义的行为?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn