13

null 関数ポインターを呼び出すと、どのような動作になりますか?

void (*pFunc)(void) = NULL;  
pFunc();

まだ使用されていない関数ポインタを NULL に初期化することが推奨されるのはなぜですか?

4

3 に答える 3

13

C および C++ では、これは と呼ばれますundefined behaviour。つまり、コンパイラ、このコードを実行しているオペレーティング システム、環境 (など... ) 意味。

関数へのポインター、または一般的に NULL へのポインターを初期化すると、一部の開発者は、ポインターが初期化されておらず、ランダムな値と等しくないことを確認して、誤って逆参照するのを防ぐことができます。

于 2013-02-26T13:13:38.957 に答える
2
  1. NULL にアクセスしようとするとどうなりますか? 以下はコードだけでなくデータにも当てはまります。これは、NULL (または 0 から 4096 までの任意のアドレス、つまりセグメントの少なくとも最初のページ) を読み込もうとしたときに起こることです。この根本的な原因は、OS とマイクロプロセッサのセグメンテーション/ページング アーキテクチャにあります。

    NULL (または 0) アドレスにアクセスしようとすると、データまたはコード セクションのいずれかで、セグメンテーション フォールト (実際にはキラー ページ フォールト) が発生します。セクションの最初のページは、仮想アドレス空間外 (または無効な部分) として扱われます。これは、意図的に最初のページが無効なまま (または存在しない) であるため、ポインターに含まれる少なくとも 1 つのアドレスが、実行時にプログラムで無効として表される可能性があります。

    1 番目のページ (仮想アドレス 0、NULL を含む) のページ記述子には、最初のビットが 0 (無効なページを意味する) として「存在」します。NULL ポインター (0 アドレス) にアクセスしようとすると、ページが存在しないためページ フォールトが発生し、OS はこのページ フォールトを処理しようとします。ページ フォールト ハンドラーが、仮想アドレス空間の無効な部分として扱われる最初のページにアクセスしようとしていることを確認すると、プロセスを強制終了します。これはすべてユーザー空間プロセスに関するものです。システム プロセス (カーネル レベルのコード) で NULL ポインターにアクセスしようとすると、OS が失敗し、システムがクラッシュします。

    リンク: http://en.wikipedia.org/wiki/Page_fault#Invalid http://en.wikipedia.org/wiki/Memory_protection#Paged_virtual_memory http://pdos.csail.mit.edu/6.828/2005/readings/ i386/s05_02.htm

    上記で十分ですが、これも読むべきだと思います http://www.iecc.com/linker/linker04.txt

  2. 関数ポインタが NULL に初期化されるのはなぜですか? ただし、 を NULL で呼び出そうとすると、ページ/セグメント フォールトが発生します。NULL は無効な機能を意味します。ガベージアドレスが含まれているが、コードセクションの有効な仮想アドレス空間にある場合、そのアドレスのコードが呼び出され、さらに災害になる可能性があります(リアルタイムシステムの場合はspl)。funcp = funct_foo_name + 1; を初期化します。関数ポインタを使用して関数を呼び出すようになりました。関数ポインターは、コード セクションの有効な仮想アドレス空間を指しています。bt 関数は、間違った場所から実行を開始します。これにより、間違ったコードが実行されたり、順序が間違ったりする可能性があります。

于 2013-02-26T14:42:40.853 に答える
0

:への「通常の」(データ) ポインターを初期化するのと同じ理由で、NULLエラーの追跡が容易になる可能性があるため、推奨されます。もちろん、これが役立つかどうかについての意見はさまざまです:-)

于 2013-02-26T13:11:01.223 に答える