Code Fix

上級

Assertion failed の原因と直し方

assert()に渡した条件式がその場でfalseになったときに強制終了するマクロです。「本来ありえないはずの状態」を検出するために使われます。

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

main: main.c:6: main: Assertion `score > 100' failed.
main: main.c:6: main: Assertion `score > 100' failed.
メモリ管理システム(またはassert)が不整合を検知して出したメッセージ
Aborted
この後プロセスは強制終了します(Aborted)

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

パターン1

 1  #include <stdio.h>
 2  #include <assert.h>
 3  
 4  int main(void) {
 5      int score = 85;
 6      assert(score > 100 );
                     ^
 7      printf("score=%d\n", score);
 8      return 0;
 9  }
main: main.c:6: main: Assertion `score > 100' failed. Aborted

assert()は渡した条件式がその場でfalseになると強制終了します。scoreは85で100を超えていないのに「100より大きいはず」と誤った前提を書いてしまうと、プログラマ自身のロジックミスとして検出されます。

直し方: score > 100score <= 100 にします。

この問題を解いてみる →

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

パターン2

 1  #include <stdio.h>
 2  #include <assert.h>
 3  
 4  int main(void) {
 5      int stock = 0;
 6      assert(stock > 0 );
                    ^
 7      printf("stock=%d\n", stock);
 8      return 0;
 9  }
main: main.c:6: main: Assertion `stock > 0' failed. Aborted

在庫が0であること自体は正常なケースかもしれません。「0はありえない」という誤った前提のassertを書くと、正常な状態でも強制終了してしまいます。

直し方: stock > 0stock >= 0 にします。

この問題を解いてみる →

パターン3

 1  #include <stdio.h>
 2  #include <assert.h>
 3  
 4  int main(void) {
 5      int temp = 36;
 6      assert(temp < 0  );
                    ^
 7      printf("temp=%d\n", temp);
 8      return 0;
 9  }
main: main.c:6: main: Assertion `temp < 0' failed. Aborted

assertは「本来ありえないはずの状態」を検出するためのものです。前提そのものを書き間違えると、正常な値でも強制終了の原因になります。

直し方: temp < 0temp >= 0 にします。

この問題を解いてみる →

よくある誤解

assertはエラーハンドリングの代わりではありません。ユーザー入力のような「起こりうる」異常はif文で処理すべきで、assertは「プログラマのロジックの前提が崩れていないか」を検査するための開発時のツールです。NDEBUGを定義してビルドすると、assertはまるごと消え去ることにも注意が必要です。

まとめ

Assertion failedは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

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