セグメンテーション違反とは、プログラムのエラーの一つである。シグナル名に由来して短くSEGVともいう。 セグメンテーションフォルト。segfault。一般保護違反。
簡単に言うとプログラムがメモリの変なところを操作しようとするとこのエラー(例外)が発行される。 これをやってしまったプログラムは、SIGSEGVというシグナルがOSカーネルから送信され、「セグメンテーション違反です」などという メッセージとともに落ちる。これを連発するプログラムは品質が低いと言うことになる。
かつて全世界の人間を恐怖に陥れたブルースクリーンはだいたいこれが原因である。 最近ではこなれてきてシステム全部がだめになると言うことは少なくなったが、 「問題が発生したため、xxx を終了します。ご不便をかけて申し訳ありません。」というふざけたメッセージで 利用者を不愉快にさせるのは変わりない。
プログラムのバグによって起こるエラーなので、利用者側ではこれを直すことができない。 できることといえば、開発者にバグ修正を依頼、SEGVが起こる機能を使わないということぐらいしかない。
具体的には以下のような状況でSEGVが起こる:
SEGVはこのような些細なミスで起こる。このためメモリ周りのバグは見つけにくく、機能追加や仕様変更を繰り返していくとどこでどうやってバグが引き起こされたのかがすぐにわからなくなってしまうことがしばしばある。 まずSEGVが起こった状況と原因から特定していかないといけないため、動作環境を少しずつ変えながらステップ実行を行うという単調な作業を繰り返すハメになる。これで開発者はうんざりしてやる気がなくなってしまい、仕様ということにしたり、最後には投げ出してしまうことも多い。というわけでバグ報告をするときは、動作環境と再現方法を書いてもらえるととても助かるんです。
以下は無効なメモリ領域を操作することによってSEGVを起こす簡単なサンプル。
int main(void) {
int *p;
*p = 1;
/* この時点でpはどこを指しているかわからないのでおそらくSEGVになる。 */
return 0;
}
掲示板
20 ななしのよっしん
2022/03/19(土) 22:24:11 ID: gTFvDj/yk7
例えばJava言語なら、ユーザーのプログラムでセグメンテーション違反を直接引き起こす可能性は極めて低いかもしれない。
ただし、セグメンテーション違反は発生しなくても、nullにアクセスすればNullPointerExceptionが、配列外にアクセスすればArrayIndexOutOfBoundsExceptionが発生してプログラムが止まるかもしれない。
結局、あるべきエラーチェックや例外処理がきちんとプログラムで行われているかが重要であって、セグメンテーション違反を回避するために言語を選択するという行為は本質的な対策にはならないと言わざるを得ない。
21 ななしのよっしん
2023/02/27(月) 12:01:11 ID: EXbjtZ7OJm
ElmとかRust(unsafeはなし)みたいな型がかなり厳重な言語だとそういう類のエラーは弾けるのでは?
22 ななしのよっしん
2024/05/30(木) 18:03:23 ID: tIi+hsZWE+
Rust SEGV without unsafeとかで調べるとOSレベルからメモリ操作してSEGV引き起こすこともできるっぽいね(擬似ファイルシステムの/proc/self/memを利用する)
safeなRust世界で完結すればSEGV出ないだろうけど、より低いレイヤへのアプローチが出来ればSEGVは起こりうるんじゃないかな
極端な話、宇宙線でビット反転が起きてSEGVが出ることもあるでしょう
急上昇ワード改
最終更新:2025/12/12(金) 11:00
最終更新:2025/12/12(金) 10:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。