43

32ビットシステム(Linux、Mac OS、Windows、PowerPCまたはx86)のC ++開発では、次のように、そうでなければ未定義になる(たとえば、適切な値をすぐに取得できない)ポインターを初期化しました。

int *pInt = reinterpret_cast<int *>(0xDEADBEEF);

(タイピングとDRYを節約するために、右側は通常定数になります(例:BAD_PTR))。

pIntが適切な値を取得する前に逆参照されると、ほとんどのシステムですぐにクラッシュします(一部のメモリが上書きされたり、非常に長いループに入ったりしたときにクラッシュするのではなく)。

もちろん、動作は基盤となるハードウェアに依存します(ユーザープロセスから奇数アドレス0xDEADBEEFから4バイトの整数を取得することは完全に有効かもしれません)が、クラッシュはこれまでに開発したすべてのシステムで100%信頼できます( Mac OS 68xxx、Mac OS PowerPC、Linux Redhat Pentium、Windows GUI Pentium、WindowsコンソールPentium)。たとえば、PowerPCでは、奇数アドレスから4バイト整数をフェッチすることは不正です(バスエラー)。

64ビットシステムでこれに適した値は何ですか?

4

12 に答える 12

71

0xBADC0FFEE0DDF00D

于 2009-08-11T01:27:33.023 に答える
55

Wikipedia によると、BADC0FFEE0DDF00D は IBM RS/6000 64 ビット システムで使用され、初期化されていない CPU レジスタを示します。

于 2009-08-11T01:28:28.780 に答える
27

現在のほとんどの 64 ビット システムでは、アドレス空間の最下位の 2 48 ~ 2 52ビットしか使用できません。アドレスの上位ビットはすべてゼロでなければなりません。一部のチップ (例: amd64) では、最大の2 48 –2 52も使用できます。これらの範囲外のアドレスは、アクセス可能なメモリにマップできません。ハードウェアは単にそれを許可しません。

したがって、2 63に近い値を使用することをお勧めします。これは、使用可能なスペースのいずれにもほど遠いものです。16 進数の先頭 4 桁が 7ff8 の場合、値は倍精度浮動小数点 NaN になるので便利です。したがって、私が提案するかわいい 16 進数のフレーズは 0x7FF8BADFBADFBADF です。

ところで、実際には 0 に近い値を使用することは望ましくありません。これは、 NULL のオフセット逆参照 (構造体メンバー アクセスなど) と有害パターンの逆参照を区別するのが難しくなるためです。

于 2010-08-02T20:40:19.893 に答える
25

一般に、どのパターンを作成するかは重要ではありません。問題が発生している場所を特定するために、パターンを識別できることが重要です。Linuxカーネルでは、アドレスが逆参照された場合にトラップできるように、これらが選択されることがよくあります。

include / linux/poison.hでLinuxカーネルを見てください。このファイルには、さまざまなカーネルサブシステムのさまざまなポイズン値が含まれています。適切な毒の価値はありません。

また、特定のアーキテクチャで何が使用されているかについては、Linuxカーネルソースツリーのアーキテクチャごとのインクルードファイルを確認することもできます。

于 2010-08-02T15:20:56.047 に答える
14

私はあなたがすでに NULL を割引していると仮定しています (つまり、型キャストなしの 0)。理論的には、有効なポインタはメモリ アドレス 0xDEADBEEF (またはその他の非 NULL メモリ アドレス) を指す可能性があるため、間違いなく最も安全な選択です

于 2009-08-11T01:27:19.780 に答える
13

0xDEADBEEFBAADF00D動作する可能性があります。

于 2009-08-11T01:26:31.963 に答える
8

適切な選択肢はありませんが、フレーズを作成するために使用できる16 進語のリストを次に示します。

于 2009-08-11T01:29:11.460 に答える
5

2 つの 0xDEADBEEF で十分だと思います..

于 2010-08-02T15:02:37.597 に答える
3

NULL が良い選択であると主張する回答がいくつか見られますが、私は同意しません。

NULL は、関数からの有効な戻り値としてよく使用されます。失敗の戻り値または不明な値を示します。これは「未初期化ポインタ」とは意味が異なります。

コードでデバッガーを使用して NULL を確認すると、2 つの可能性が残ります。ポインターが初期化されていないか、メモリ割り当てに失敗したかです。

初期化されていないポインタを 0xDEADBEEF または 64 ビットに相当する値に設定することは、NULL ポインタが意図的な値を示すことを意味します。

于 2009-08-11T02:50:43.887 に答える
2

もちろん、OSや環境によって異なります。0xDEADBEEF が、任意の 32 ビット システムで必ずしも悪いポインターだとは思いません。

現実的には、最新の OS はプロセス メモリの最初の数ページをアクセス保護する必要があるため、NULL は適切な無効なポインター値である必要があります。便利なことに、それはすでに事前に定義されています。

于 2009-08-11T01:31:44.423 に答える
1

0x4232ビットと64ビットの両方で動作しますか? (NULL ポインターに十分近いため、それでもクラッシュを引き起こすはずです。また、かなり大きいため、構造体ポインターが NULL である構造体フィールドの通常の逆参照内ではクラッシュしない可能性があります)。

于 2009-08-11T01:29:46.517 に答える