Code Fix

初級

Segmentation fault(NULLポインタの参照)

NULL(何も指していないポインタ)の指す先を読み書きしようとしたときに発生するクラッシュです。Cで最も頻出する実行時エラーです。

エラーメッセージの読み方

Segmentation fault
(エラーメッセージなし)
これはプログラム自身の出力ではありません。プログラムは何も言わずに落ちています
Segmentation fault
シェルが検知した異常終了の種類 — OSが「不正なメモリアクセス」などを検出しプロセスを強制終了させました
見つけ方
このメッセージだけでは行番号すら分かりません。原因はコードを読んで特定するしかありません

このエラーが出る典型パターン

パターン1

 1  #include <stdio.h>
 2  #include <stdlib.h>
 3  
 4  int main(void) {
 5      int *p = NULL               ;
                          ^
 6      printf("%d\n", *p);
 7      return 0;
 8  }
Segmentation fault

NULLは「何も指していない」という印です。*pでその指す先を読もうとした瞬間、無効なアドレスへのアクセスとしてクラッシュします。

直し方: NULLmalloc(sizeof(int)) にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <stdio.h>
 2  #include <stdlib.h>
 3  
 4  int main(void) {
 5      int value = 7;
 6      int *p = NULL  ;
                    ^
 7      *p = value;
 8      printf("%d\n", *p);
 9      return 0;
10  }
Segmentation fault

pがNULLのまま*p = valueで書き込もうとすると、読み込みと同様にクラッシュします。有効な変数のアドレス(&value)を指すようにする必要があります。

直し方: NULL&value にします。

この問題を解いてみる →

パターン3

 1  #include <stdio.h>
 2  #include <stdlib.h>
 3  
 4  int main(void) {
 5      int *p = malloc(sizeof(int));
 6      p = NULL     ;
                ^
 7      *p = 1;
 8      printf("%d\n", *p);
 9      return 0;
10  }
Segmentation fault

せっかくmallocで有効な領域を確保していても、途中でpにNULLを代入し直すと、その後の*pは無効な参照になります。

直し方: NULLp にします。

この問題を解いてみる →

よくある誤解

NULLを代入した行では何も起きません。実際にそのポインタを*pや->で参照した瞬間にクラッシュします。関数がNULLを返す可能性がある場合(mallocの失敗など)、使う前にNULLチェックをしないと危険です。

まとめ

Segmentation fault(NULLポインタの参照)は初級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)