注意: この記事は1年以上前に掲載されたものです。情報が古い場合がありますのでお気を付け下さい。
C言語およびC++の配列は他の言語と比較して使用するには気をつけなければならないことがある。配列外参照は特に要注意で、他の言語の多くではランタイムエラーが発生して処理が止まるが、C言語やC++では一見すると正常に動いているように見えてメモリー内容の破壊を引き起こしてしまうこともある。
たとえば以下のような構造体がある。(インクルード等は割愛)
[code lang=”c”]struct Something {
int arr[5];
int val;
}
[/code]
本来、配列arrの範囲外であるarr[5]に代入しようとすれば異常終了するように考えられるはずだが、実際にはそうはならず、valの値を書き換えてしまうという事態が発生することがある。その場合においては、そのvalの値で何らかの配列などのインデックス値として使うといった場合、他の構造体をはじめとした各種変数やポインターなどを破壊して回っていくようになってしまうため、意図せぬ動作を引き起こしてしまう。
これはバッファーオーバーフローの例であり、C言語のダークサイドのひとつでもある。C言語やC++の配列においてはパフォーマンスを重視する傾向が非常に強く、通常の配列では範囲のチェック処理を行わない模様で、本来なら配列外である領域にまでアクセスできてしまうという問題点を抱えている場合が多い。
これは、意図せぬところで発生して、非常に面倒なバグを引き起こす危険性が非常に高いため、特に気をつけるべきだろう。
ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しています。主にスマートフォン向けアプリやウェブアプリの開発を携わっています。ご用の方はコメントかコンタクトフォームにて。
コメント
C++11 以降であれば std::array を使うことが可能で、array::at() を使えば境界チェックも働きます。
>mitei様
コメントありがとうございます。
記事においてはその説明をしていなかったのですが、その通りですね。
補足情報ありがとうございます。