C++_宣言した添え字の範囲外に代入した時

※生配列。std::array の場合は不明。
※C 言語サイトを参照してるので、違うところあるかも。

結論から

エラーが出なくとも他の変数 ( 値が変わったりなど ) 影響する可能性がある。
故に、宣言された範囲外のインデックスを持つ配列要素への代入は NG

回避する為にif 文かませたり、assert 文を使う。

 

詳しく。

それぞれ実行した時の結果。

int unManagedArray[ ] = { 1, 2, 3, 4 };

//unManagedArray[4];        //エラーなし
//unManagedArray[10];       //エラーなし
//unManagedArray[100000];   //エラーなし

//unManagedArray[4] = 5;  //強制終了
//unManagedArray[10] = 5;   //エラーなし
//unManagedArray[100000] = 4;    //エラー発生

なお、
unManagedArray[4] = 5;
を別の日に試したらエラーなし、となった。

 

代入時、何が起きているのか

範囲外の unManagedArray[n] = x; を実行した時、( n は範囲外 )
プログラムはメモリ上のどこかの場所を実在していない unMa~[n] とみなし、
そこへ値 x を代入しようとする。

unM~[n] とみなされたメモリ領域は次の可能性がある。

1.OS からそのプログラムに割り当てられたメモリ領域ではない

2.そのプログラムに割り当てられた領域内であるが、そこに他の変数がある

3.そのプログラムに割り当てられた領域内であり、そこに他の変数がない

 

1.~  3.によってプログラムの挙動が違ってくる。

1.の場合
OS がプログラムを強制的に終了させ、
セグメントエラー などのエラーメッセージを出す。

強制終了するので誤りがあることが分かる。

 

2.の場合
unM~[n] = x という代入によって、他の変数がもつデータが破壊され、
プログラムは期待通りの動きをしない

変数が破壊されるタイミングが、破壊される変数を
使用している時ではないので、誤りがどこか見つけるのが難しい。

 

3.の場合
期待通りの動きをするが次回プログラムを起動した時
同じ動きをするとは限らない

誤りがあることに気づかないまま使用続けて、
プログラムが突然正常に動かなくなったりする

 

なお、 unManagedArray[100000] = 4; においては、
添え字の範囲を大きく逸脱した場合はセグメントエラーになる場合が多い。

 

 

C#C ++/C L I では
追加情報:インデックスが配列の境界外です」という例外が発生する。
下記両方ともエラーが発生するコード。

C #

int cArray = new int { 1, 2, 3, 4 };
Console.WriteLine(cArray[4].ToString()); 

 

C ++/C L I

array<int> ^ innna = gcnew array<int> { 1, 2, 3, 4 };
innna[4] = 5;

 

 

こちらから。
http://www.cc.kyoto-su.ac.jp/~yamada/programming/array.html
http://code.i-harness.com/ja/q/12eb82
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1496296189
http://worthliv.com/cpp_assert.html

 

以上。