NULL ポインターでのクラス メンバーへのアクセス: 異常と説明
提供された C コード スニペットでは、関数呼び出しが非仮想メソッドはオブジェクト ポインタが NULL であっても成功しましたが、仮想関数呼び出しによりアプリケーションがクラッシュしました。この奇妙な行動は、2 つの基本的な疑問を引き起こします:
1.非仮想メソッドは NULL ポインターでどのように動作しますか?
仮想関数呼び出しとは異なり、非仮想関数呼び出しでは vtable ルックアップが必要ありません。コンパイラは、関数呼び出しを、実行される特定の関数を指すマシンコード命令に直接変換します。関数には、関数が呼び出されるオブジェクトへのポインタが隠しパラメータとして渡されます。
指定されたコードでは、関数 Say_hi() は Foo クラスのメンバーを参照しません。したがって、 this ポインタを逆参照する必要なく実行できます。基本的に、say_hi() の呼び出しは次と同等です。
void Foo_say_hi(Foo* this); Foo_say_hi(foo); // where foo is NULL
関数はオブジェクトのメンバーへのアクセスを試みないため、NULL ポインターの逆参照という未定義の動作は発生しません。
2.オブジェクト foo はどこに割り当てられますか?
提供されたコードでは、foo は Foo* 型のローカル変数として宣言されています。特定のメモリ割り当てが与えられていないため、他のローカル変数と同様に、main 関数のスタックに割り当てられる可能性が高くなります。ただし、foo に格納されている値は NULL ポインターであり、Foo 型の有効なオブジェクト インスタンスを指していないことを示しています。
以上が仮想関数の呼び出しは失敗するのに、非仮想関数の呼び出しは NULL ポインターで成功するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。