C++ 多维数组的索引超出范围是否为未定义行为?

C++ 多维数组的索引超出范围是否为未定义行为?,c++,multidimensional-array,C++,Multidimensional Array,我知道使用超出数组范围的索引会导致未定义的行为 但是,这样的多维数组呢: int aa[][2]{ {5,7}, {23, 16}, {81, 83} }; cout << aa[0][0] << endl; cout << (*aa)[0] << endl; cout << aa[0][1] << endl; cout << (*aa)[1] << endl;

我知道使用超出数组范围的索引会导致未定义的行为

但是,这样的多维数组呢:

int aa[][2]{ {5,7}, {23, 16}, {81, 83} };
    cout << aa[0][0] << endl;
    cout << (*aa)[0] << endl;
    cout << aa[0][1] << endl;
    cout << (*aa)[1] << endl;
    cout << aa[0][2] << endl; // here
    cout << (*aa)[2] << endl; // and here
intaa[][2]{{5,7}、{23,16}、{81,83};

cout实际上,您看到的结果是,因为当您访问数组时,编译器使用UB

当您通过
aa[i][j]
访问变量时,编译器计算访问的地址如下(C使用内存布局):

但是如果
i
或/和
j
超出范围怎么办?编译器应该做什么

如果不是UB,编译器将不得不发出一些代码来检查范围,如果违反范围,则抛出一个错误

然而,由于这种情况下UB,因此生成的程序可以执行它喜欢的任何操作:

  • 格式化硬盘
  • 从您的帐户发送令人尴尬的消息
  • 撞车
  • 只要应用上面的公式
对于编译器程序员来说,最简单的方法是选择最后一个选项,这对我所知道的所有编译器都是如此(但你无权假设将来会出现这种情况——也许一个普通的编译器程序员会选择前两个选项中的一个!)


使用上述公式,
aa[0][2]
的地址与
aa[1][0]
的地址相同(即偏移量
2
),这解释了您看到的结果。

“但当我使用aa[0][2]时,我得到的是23,而不是未定义的行为?”-不,您得到的是未定义的行为。这可能意味着你的程序看起来“有效”。当你说你没有未定义的行为时,我不确定你期望什么。未定义的行为可能是从代码似乎起作用到向月球发送太空摇杆。它不会总是给出一个错误。它是未定义的。@NeilButterworth:这也是UB:
cout是的,
aa[0][2]
(*aa)[2]
是UB@M.M:谢谢。现在明白了。重新格式化硬盘以惩罚编码错误的编译器绝对是最糟糕的:)
address_of(aa)+2*i+j  # 2 elements in a row