ProgrammingC 開発者

C言語における「未定義動作」とは何ですか?その発生例と問題を最小限に抑える方法を示してください。

Hintsage AIアシスタントで面接を突破

答え。

未定義動作(UB) とは、C言語の標準が結果を定義していないプログラムの動作です。コンパイラやシステムは、目立たないエラーから完全なクラッシュやデータの損傷まで、あらゆる行動をとる可能性があります。

未定義動作の典型的な原因:

  • 配列の範囲外アクセス
  • 初期化されていない/無効なポインタの逆参照
  • 0での除算
  • 定数の変更

未定義動作を最小化する方法:

  • 変数は常に初期化する
  • 配列のインデックスを確認する
  • コードの静的および動的解析ツール(例:valgrind、AddressSanitizer)を使用する

コード例:

int arr[5]; arr[10] = 0; // UB — 配列の範囲外アクセス int* p = NULL; *p = 42; // UB — NULLポインタの逆参照

トリビアの質問。

質問: 整数を0で割った場合、プログラムはどうなるか?

答え: C標準(ISO C99 6.5.5)では、0での除算は未定義動作です。クラッシュ、ゴミの発生、または「論理的に正しい」出力があるかもしれませんが、標準は結果を保証しません。

コード例:

int a = 10, b = 0; printf("%d", a / b); // 未定義動作

歴史

組み込みシステムのプロジェクトの1つで、プログラマが配列の範囲を超えて1つの要素にアクセスするループを書きました。アプリケーションは正常に動作しましたが、1ヶ月後にメモリ内の他のデータが破損し始めました(短期的なエラーで、複製が難しい)。問題は、詳細なレビューと静的解析ツールによるチェックの後に発見されました。


歴史

開発者はNULLポインタの逆参照が常にクラッシュを引き起こすと考え、NULLチェックを追加しませんでした。しかし、珍しいプラットフォームでは、不正確(しかし致命的でない)なメモリの変更が発生し、他の構造が壊れ、追跡が難しいバグが引き起こされました。


歴史

擬似乱数生成に除算を利用し、引数のいくつかの値で0での除算が発生しました。ほとんどのプラットフォームではプログラムが単に「クラッシュ」しましたが、あるプラットフォームでは結果が不正確な数値となり、異なる環境間でバグの再現が不可能になりました。