ポインターの有効性をテストする (C/C++)

そのチェックはできません。ポインタが「有効」かどうかを確認する方法はありません。人々がポインターを取る関数を使用するとき、彼らは自分が何をしているかを知っていると信じなければなりません。ポインタ値として 0x4211 が渡された場合、それがアドレス 0x4211 を指していることを信頼する必要があります。そして、彼らが「偶発的に」オブジェクトに当たった場合、恐ろしいオペレーティング システム関数 (IsValidPtr など) を使用したとしても、バグに陥り、すぐに失敗することはありません。

この種のことを通知するために null ポインターの使用を開始し、ライブラリのユーザーに、誤って無効なポインターを渡す傾向がある場合はポインターを使用すべきではないことを真剣に伝えてください:)


ここでは、Linux で C プログラムが実行されているメモリの状態について内省するための 3 つの簡単な方法と、特定のコンテキストで質問に適切で洗練された回答がある理由を示します。

<オール>
  • getpagesize() を呼び出してポインターをページ境界に丸めた後、mincore() を呼び出して、ページが有効かどうか、およびプロセスのワーキング セットの一部であるかどうかを調べることができます。これにはいくつかのカーネル リソースが必要になるため、ベンチマークを行って、この関数の呼び出しが API で本当に適切かどうかを判断する必要があります。 API が割り込みを処理する場合、またはシリアル ポートからメモリに読み取る場合は、予測できない動作を避けるためにこれを呼び出すことが適切です。
  • stat() を呼び出して利用可能な /proc/self ディレクトリがあるかどうかを判断した後、/proc/self/maps を開いて読み、ポインタが存在する領域に関する情報を見つけることができます。proc のマニュアル ページを調べてください。 、プロセス情報疑似ファイルシステム。明らかに、これは比較的コストがかかりますが、解析の結果を配列にキャッシュすることで回避できる可能性があります。バイナリ検索を使用して効率的に検索できます。 /proc/self/smaps も考慮してください。 API がハイ パフォーマンス コンピューティング用である場合、プログラムは、不均一なメモリ アーキテクチャである numa のマニュアル ページに記載されている /proc/self/numa について知りたいと考えます。
  • get_mempolicy(MPOL_F_ADDR) 呼び出しは、複数の実行スレッドがあり、CPU コアとソケット リソースに関連する非均一メモリとの親和性を持つように作業を管理しているハイ パフォーマンス コンピューティング API 作業に適しています。もちろん、そのような API は、ポインタが有効かどうかも教えてくれます。
  • Microsoft Windows には、プロセス ステータス API (NUMA API にもあります) で文書化されている関数 QueryWorkingSetEx があります。洗練された NUMA API プログラミングの結果として、この関数を使用すると、ポインタの有効性を簡単にテストすることもできます (C/C++)。


    呼び出し元が無効なポインターを送信することによって引き起こされるクラッシュを防ぐことは、見つけにくいサイレント バグを作成するための良い方法です。

    API を使用しているプログラマーは、自分のコードが偽物であるという明確なメッセージを、API を隠すのではなく、クラッシュさせることによって得た方がよいのではないでしょうか?