2

静的配列とC++の動的配列の正解によると、静的配列のサイズは固定されています。

ただし、これはコンパイルされ、正常に実行されます。

int main(int argc, char** argv) {

int myArray[2];

myArray[0] = 0;
myArray[1] = 1;

cout<<myArray[0]<<endl;
cout<<myArray[1]<<endl;

myArray[4];

myArray[2] = 2;
myArray[3] = 3;

cout<<myArray[2]<<endl;
cout<<myArray[3]<<endl;

return 0;
}

これは、静的配列のサイズを変更できることを意味しますか?

4

3 に答える 3

7

いいえ、地獄のチャンスではありません。あなたがしたことは、その境界の外で不法にアクセスしたことだけです。これがたまたまエラーをスローしないという事実は、まったく無関係です。とことんUBです。

于 2012-11-18T12:02:02.057 に答える
7

実際に配列を拡大しているわけではありません。コードを詳しく見てみましょう。

int myArray[2];

myArray[0] = 0;
myArray[1] = 1;

0 から 1 までのインデックスを持つ 2 つの位置の配列を作成します。

myArray[4];

配列の 5 番目の要素 (配列に存在しないことが確実な要素) にアクセスしています。これは未定義の動作です。何でも起こりえます。その要素で何もしていませんが、それは重要ではありません。

myArray[2] = 2;
myArray[3] = 3;

ここで、要素 3 と 4 にアクセスし、それらの値を変更しています。繰り返しますが、これは未定義の動作です。作成された配列の近くのメモリ位置を変更していますが、「他には何もありません」。配列はそのままです。

実際には、次のようにして配列のサイズを確認できます。

std::cout << sizeof( myArray ) / sizeof( int ) << std::endl;

配列のサイズが変更されていないことを確認します。ところで、このトリックは、配列が宣言されているのと同じ関数で機能します。配列を渡すとすぐに、ポインターに減衰します。

C++ では、配列の境界はチェックされません。主にそれが原因で、エラーや警告は表示されませんでした。ただし、配列の制限を超えて要素にアクセスすることは未定義の動作です。未定義の動作とは、すぐには表示されない可能性があるエラーであることを意味します (一見良いが、実際にはそうではありません)。プログラムでさえ問題なく終了できるようです。

于 2012-11-18T12:08:35.360 に答える
5

まず、これは静的配列ではなく、自動ストレージに割り当てられた配列です。

次に、

myArray[4];

は新しい宣言ではなく、以前に宣言された 2 要素配列の要素 #4 からの破棄された読み取りです - 未定義の動作です。

次の課題

myArray[2] = 2;
myArray[3] = 3;

プログラムに割り当てられていないメモリへの書き込み-未定義の動作も同様です。

于 2012-11-18T12:02:33.210 に答える