2012-02-12 6 views
5

私がnew(またはmalloc)を実行しているときにC++で、戻り値が特定の値よりも大きくなるという保証はありませんか?なぜなら...このプロジェクトでは、enumとして0-1kを使用することは非常に便利だと分かります。しかし、その価値を低くすることが可能なら、私はそれをしたくありません。私の唯一のターゲットシステムは、OSウィンドウ/ linuxとmacを持つ32または64ビットのCPUです。ポインタはある値以上になることが保証されていますか?

標準ではポインタに関することは何ですか?ウィンドウやLinuxは、CランタイムとRAMの最小メモリアドレスについて何か言いますか?

-edit-最終的に私のnewオーバーロードがアドレスが> 1kを超えているかどうかを確認するように変更しました。私はstd :: terminateを呼び出します。

+1

なぜenumをポインタとして使用していますか? – Pubby

+1

@Pubby:(特にインタプリタやゲームでは)プラットフォーム固有のポインタの特性に依存して、通常は間接を排除するために余分な情報を入れるのが一般的です。アラインメントルールのため、下位3ビットは空きです。さらに、64ビットシステムでは一般に、有効ビット数が48のユーザー空間ポインタしかありません。残りは '1'または' 0'なので、 'double'の(53ビット)仮数に' NaN'を表すように上位ビットを設定してポインタをパックすることができます。次に、低次フラグを使用すると、マスキングとシフトを使用して表現をすばやく選択できます。 –

+0

私は最初の1または4k:を必要としないので、私は6ビットしか必要ではないようです。 –

答えて

4

このような保証はありません。非常に特定のメモリ位置が必要な場合はplacement newを試すことができますが、特定の問題があります。具体的には、work hard to avoidです。代わりにポインタをその値として持つ整数キーを持つマップを使用してみてください。そうすれば、特定のメモリアドレスと範囲に頼る必要はありません。

2

理論的には、ポインタは0以上であることも保証されていません。しかし、実際には、符号なし整数(ポインタが高位の "1"ビットを持つことを忘れないでください)私が知っているシステムは、約1000未満のポインタ値を持つことはありません。しかし、それに依存することは "未定義の動作"に依存しています。

+1

を参照してください私は、Linux仮想メモリの最初の1GBはカーネルのためだけであることを思い出していると思います[もしそれが本当であれば、あなたのアプリケーションはカーネルモードで動かない限り、最初の1GBのアドレスを取得しません。 \ – amit

+0

@amit私のgoogle-fuは、このhttp://linux-mm.org/HighMemory "ユーザプログラム用に3GB、カーネル用に1GB"を思いついたと思います。 –

+0

@amit - 私は非常に一般的に話していました.C++はかなり小さなシステムで動作します。 –

1

有効なメモリアドレスがどこから来たのかに関する標準はありません。安全なシステムに依存しないコードを書くためには、特定のアドレスに依存することはできません(また、逸話的なサポートがあっても、いつ新しいシステムアップデートで変更されるかわかりません)。

6

標準では何もありません。しかし実際には、それはターゲットOSに依存します。たとえば、Windowsはメモリの最初の64kbを無人島として予約します(ビルドに応じて、読み取り専用メモリ、それ以外はPAGE_NOACCESSとしてマークされます)。カーネルメモリの場合は0x80000000 +を上回りますが、変更することができます。MSDNの thisを参照してください。

x64では、アドレスの上位ビット(現在のアドレスには47ビットしか使用されていません)を使用することもできますが、後で変更され、プログラムが中断するような良い考えはありません標準もそれに対して助言する)。

+0

良い答え+1。 –

1

NULLを常に0x0にあることが保証されるなど非常にプラットフォーム固有ですので、あなたは非常に良い理由があると移植のための結果を認識していない限り、私はこの種の情報に頼って思いとどまらなり、メンテナンス性。私が正しく思い出すと、x86は最初の128 MBのアドレス空間を "NULLに相当する"として予約しているので、有効なポインタはこの範囲の値を取ることができません。 x64には、少なくとも現時点では実際には遭遇しないであろうadditional addressesがあります。

オペレーティングシステム用に予約されているアドレス空間は、OSによって異なります。 Linuxでは、カーネル内でカーネルユーザ空間分割が設定可能であるため、少なくとも3つの分割:1〜3 GB、2〜2 GB、3〜1 GBは32ビットシステムで共通です。詳細はon kerneltrapです。

+0

アドレス空間の最初の128 * K * Bを意味しますか? –

+0

@CodyGrayいいえ、実際は128 MBで、kBではありません。しかし、私はその原因について正しくはありませんでした。これはCPU自体に起因するものではなく、ほとんどのUNIXライクなシステムでのアプリケーションのアドレス空間のレイアウトによってもたらされます。 0-128 MBの領域はスタック用に予約されています。つまり、ヒープからメモリを割り当てる 'new'または' malloc() 'を使用しているときは、この範囲からアドレスを取得しません。それは[この素敵な答え](http://stackoverflow.com/a/2187753/1224016)で非常によく説明されています。 –

関連する問題