私の質問は、4GBのアドレス指定可能なシステムのメモリ管理に関するもの
char *p = NULL;
です。それはメモリを占有しますか?
もしそうなら、ヒープまたはスタックのどこに、いくらですか?また、char **p=NULL;
3 に答える
一般的な32ビットシステムでは、4バイトかかります。
あなたの例がいくつかの関数のローカル変数の定義であると仮定すると、それらのバイトはスタックから取得されます。それでも:
- 変数が他の場所で使用されていない場合、コンパイラーは生成されたコードから変数を完全に削除する可能性があります。
- 変数がローカルでのみ使用され、そのアドレスが取得されない場合、変数はレジスタに入れられる可能性があるため、「通常の」メモリを占有しません。
代わりに、それがグローバル変数(または一般に静的ストレージ期間を持つ変数)である場合、ほとんどのシステムには、それらに使用される特別なメモリ領域(スタックおよびいわゆるヒープから分離されている)があります。多くの場合、コピーオンライトモードで実行可能イメージから直接マップされたメモリ領域です。したがって、ここでは、実行可能ファイル内のスペースで、この特定のメモリ領域の両方で4バイトが占有されています。
同じことがに当てはまりますchar **p。これは、原則として、より大きくなったり、何らかの形でとは異なる理由はありませんchar *。
ちなみに、char * pまたはchar ** pが集約データ型(通常はstruct)の一部である場合、それらが取るスペースは、structが割り当てられている場所から取得されます-struct変数がローカル変数である場合、スタックから取得mallocされます。ヒープ、グローバルの場合は、グローバル用の特別なメモリ領域から取得されます。sが占めるスペースについて話すstructと、パディングに関する追加の考慮事項が関係することに注意してください。
これらはすべて、「一般的な」32ビットシステムに有効な考慮事項であることに注意してください。奇妙なアーキテクチャchar **のサイズが異なることを妨げるものは何char *もありません(ただし、そうする理由はわかりません)。sizeofそれでも、演算子を使用して直接チェックを実行できます。
規格に関する限り、ポインタサイズに課せられる唯一の制約はvoid *、情報を失うことなくデータへのポインタを変換できることだと思います(実際、規格はスタックやレジスタについて言及していません)。また、「観察可能な動作」が標準から要求されたものと一貫している限り、コンパイラは必要なことを何でも実行できることに注意してください。したがって、標準で義務付けられているこれらの実装の詳細については、詳細は保証されません。使用しているコンパイラのドキュメントに記載されている場合があります。
コンテキストがない場合、変数の両方のバージョンは、通常、それぞれ1つとp1つのメモリを占有し、自動(「スタック」)または静的(「グローバル」)ストレージのいずれかになります。必要なサイズは、のサイズ(通常は1マシンワード)以下です。char*char**void*
コンパイラは、この変数がメモリに格納されているかのように常に動作できますが、値を直接置き換えることができる場合は、変数を完全に削除する可能性があります。その意味で、Cコンストラクトが特定の具体的なマシンコードになるという絶対的な保証はありません。
ポインタは、アドレスを保持できる単なる通常の変数です。変数が作成される場所はどこでも、char *変数の値に関係なく、メモリを使用します。32ビットシステムでは、ポインタの一般的なサイズは32ビットであり、64ビットマシンでは64ビットです。のようにintまたはlong。