セグメンテーション違反とは、プログラムのエラーの一つである。シグナル名に由来して短くSEGVともいう。 セグメンテーションフォルト。segfault。一般保護違反。
概要
簡単に言うとプログラムがメモリの変なところを操作しようとするとこのエラー(例外)が発行される。 これをやってしまったプログラムは、SIGSEGVというシグナルがOSカーネルから送信され、「セグメンテーション違反です」などという メッセージとともに落ちる。これを連発するプログラムは品質が低いと言うことになる。
かつて全世界の人間を恐怖に陥れたブルースクリーンはだいたいこれが原因である。 最近ではこなれてきてシステム全部がだめになると言うことは少なくなったが、 「問題が発生したため、xxx を終了します。ご不便をかけて申し訳ありません。」というふざけたメッセージで 利用者を不愉快にさせるのは変わりない。
プログラムのバグによって起こるエラーなので、利用者側ではこれを直すことができない。 できることといえば、開発者にバグ修正を依頼、SEGVが起こる機能を使わないということぐらいしかない。
具体的には以下のような状況でSEGVが起こる:
- 確保したメモリ領域を超えたところを操作してヒープやスタックを破壊する(配列オーバー)
- メモリ領域を増やすためにメモリを確保し直したが、ポインタの更新を忘れてすでに無効となった所を操作する
- エラーチェックを怠ってヌルポインタを参照する
- リテラルなど、変更不能なものを書き換える
- すでに解放した領域をまた解放する
- その他不注意で
SEGVはこのような些細なミスで起こる。このためメモリ周りのバグは見つけにくく、機能追加や仕様変更を繰り返していくとどこでどうやってバグが引き起こされたのかがすぐにわからなくなってしまうことがしばしばある。 まずSEGVが起こった状況と原因から特定していかないといけないため、動作環境を少しずつ変えながらステップ実行を行うという単調な作業を繰り返すハメになる。これで開発者はうんざりしてやる気がなくなってしまい、仕様ということにしたり、最後には投げ出してしまうことも多い。というわけでバグ報告をするときは、動作環境と再現方法を書いてもらえるととても助かるんです。
例
以下は無効なメモリ領域を操作することによってSEGVを起こす簡単なサンプル。
int main(void) {
int *p;
*p = 1;
/* この時点でpはどこを指しているかわからないのでおそらくSEGVになる。 */
return 0;
}
関連動画
関連コミュニティ
関連項目
- 5
- 0pt