2D 配列を 1D 配列として扱う: 未定義の動作
C および C では、多次元配列はメモリに連続して格納されます。ただし、一次元のインデックスを使用して多次元配列にアクセスすると、未定義の動作が発生する可能性があります。
次のコードを考えてみましょう。
int a[25][80]; a[0][1234] = 56; // Line 2 int* p = &a[0][0]; p[1234] = 56; // Line 4
行 2:
これ行は、配列 a[25][80] の境界外にある要素にアクセスしようとします。 a の最初の次元のサイズは 25 ですが、2 行目は 1235 番目の要素にアクセスしようとしていますが、これは有効範囲を超えています。これは言語定義に違反するため、未定義の動作を引き起こします。
行 4:
この行も未定義の動作を引き起こします。配列 a には 25 * 80 = 2000 個の要素があり、p は配列の先頭を指します。したがって、式 p[1234] は、有効範囲外にある配列の 1235 番目の要素にアクセスしようとします。境界を超えるポインターを使用して配列に添字を付けると、未定義の動作とみなされます。
定数式:
上記のコードの未定義の動作は、定数式にも現れます。次のコードは、未定義の動作のためコンパイルされません:
constexpr int f(const int (&a)[2][3]) { auto p = &a[0][0]; return p[3]; // Undefined behavior } int main() { constexpr int a[2][3] = { 1, 2, 3, 4, 5, 6, }; constexpr int i = f(a); }
これは、定数式での未定義の動作が依然として不正であり、コンパイラがそのようなコードを拒否することを示しています。
以上がC/C で 2D 配列を 1D 配列として扱うと未定義の動作が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。