3

昨夜、アプリケーションの segfault を追跡するのに恥ずかしい時間を費やしました。最終的に、私が書いたことが判明しました:

ANNE_SPRITE_FRAME *desiredFrame;
*desiredFrame = anne_sprite_copy_frame(&sprite->current);

それ以外の:

ANNE_SPRITE_FRAME desiredFrame;
desiredFrame = anne_sprite_copy_frame(&sprite->current);

1 行目で型付きポインターを作成し、2 行目で逆参照ポインターの値を によって返される構造体に設定しますanne_sprite_copy_frame()

なぜこれが問題になったのですか?そして、なぜコンパイラはこれをまったく受け入れたのですか? 私が把握できるのは、例 1 の問題が次のいずれかであるということだけです。

  1. ポインター用のスペースを予約していますが、ポインターが指す内容は予約していません。または
  2. (ありそうもない) 戻り値をポインタ自体のメモリに格納しようとしている
4

4 に答える 4

5

1 行目で型付きポインターを作成し、2 行目で逆参照ポインターの値を anne_sprite_copy_frame() によって返された構造体に設定します。

これらは両方とも C で許可されているため、これはコンパイラによって完全に受け入れられます。

コンパイラは、ポインターが実際に意味のあるものを指していることを確認しません。逆参照して代入するだけです。

C の最も良い点と最も悪い点の 1 つは、コンパイラがサニティ チェックをほとんど行わないことです。つまり、コンパイラは指示に従い、指示どおりに実行します。変数が適切に初期化されていないにもかかわらず、2 つの正当な操作を実行するように指示しました。そのため、コンパイル時の問題ではなく、実行時の問題が発生します。

于 2013-08-19T17:46:09.967 に答える
3

ポインターは初期化されていませんが、まだ値を持っているため、どこかを指しています。戻り値をそのメモリ アドレスに書き込むと、そこにあるものが何であれ上書きされ、未定義の動作が発生します。

技術的には、コンパイラは、構文的に有効な構造が未定義の (または予想外の可能性さえある) 動作をもたらすことを伝える仕事をしていません。

于 2013-08-19T17:46:34.217 に答える