3

スタックとヒープの主な違いを理解していると思います。

次のプログラムでは、サイズ n のオブジェクトがヒープ上に作成されます。このソファの名前のないオブジェクトを参照するポインター p がスタック上に作成され、4 バイトを占めます (少なくとも私のシステムでは)。私がよく理解していれば、参照は余分なメモリを使用しないため、それ以上のメモリは割り当てられません (スタック上の main() によって返される int を除く)。

Class Object;  // n bytes

int main() {
    Object* p = new Object();
    Object& r = *p;
    // ...
}

それでも、メモリ管理はまだ完全には明確ではありません。

1) 名前 p と r はどこに保存されていますか? どちらもローカル名なので、スタックにも入れるべきだと思いますか? これは、変数名とそれが参照するメモリの一部との間のバインディングを格納するために余分なメモリを必要としませんか?

2) ポインタの型はどこに格納されていますか? ポインターはスタック上で 4 バイトしか占有しません。これは (私が思うに) メモリ アドレスを格納するための正確なサイズです。コンピューターは、そのアドレスでどのタイプが見つかるかをどのように認識しますか?

3) (2) と同様に、ヒープ上のオブジェクトには n バイトのストレージが必要であり、それへの唯一の (直接) 参照は 0 バイトです。このオブジェクトの型はどこに格納されているので、r を使用すると、それがどの型であるかがわかりますか?

4) コンパイルされたプログラムも、その実行をガイドするためにメモリのどこかに常駐していることを理解しました。これはスタックまたはヒープにありますか、それともメモリの別の部分ですか?

4

3 に答える 3

7

名前 p と r はどこに保存されていますか?

そうではありません - 変数名は静的であり、実行時には利用できません。コンパイラは、変数が格納される場所を認識し、名前を必要とせずにそのメモリ位置にアクセスするコードを生成します。

これらは、デバッガーが変数の値を表示できるように、プログラム ファイルの特別なデバッグ セクションで使用できる場合があります。

ポインタの型はどこに格納されていますか?

そうではありません - 型も静的です (ポリモーフィック クラス型に関連付けられた限定された動的型情報を除きますが、ポインター型は除きます)。コンパイラは型を認識し、その型に適した方法で格納された値にアクセスするコードを生成します。

このオブジェクトの型はどこに保存されますか?

型が多態的である場合 (つまり、少なくとも 1 つの仮想関数を持つクラス型である場合)、型を記述するために、直接アクセスできない不特定の場所に格納された静的データがいくつかあります。dynamic_cast仮想関数呼び出し (通常は、最終オーバーライドへのポインターのテーブル) と RTTI ( で使用する継承構造の仕様、およびで使用できるtype_info構造) をサポートするのに十分なデータがありますtypeid

それ以外の場合、すべての型情報は静的です。

[コンパイルされたプログラム] はスタックまたはヒープにありますか、それともメモリの別の部分ですか?

通常のコンピューターでは、静的メモリ (コードまたはテキスト セクション) にあり、プログラムの起動時に読み込まれます。組み込みシステムでは、代わりに読み取り専用メモリにより永続的に配置される場合があります。

于 2014-11-26T09:35:18.817 に答える
3

参照は余分なメモリを使用しないため、それ以上のメモリは割り当てられません

参照がどのように実装されるかは C++ 標準では指定されていませんが、ほとんどのコンパイラはそれらをポインタと同じように実装するため、最適化されていないコードでは、(システム上で) r....

名前 p と r はどこに保存されていますか

ここに格納されているポインタのタイプはありますか?

[ ] の型はどこにr格納されていますか

それらは、実行中にコンパイラ自体の内部に存在し、おそらく生成されたオブジェクト/ライブラリ/プログラムに入れられたデバッグシンボル情報に存在し、GCCのg++ -gオプションなどを使用する場合にインタラクティブなデバッグを支援しますが、通常のC++プログラムステートメントを介して保存またはアクセスすることはできません.

コンパイルされたプログラムも、実行をガイドするためにメモリのどこかに常駐していることを理解しました。これはスタックまたはヒープにありますか、それともメモリの別の部分ですか?

コンパイルされたプログラムは、バイナリ データとマシン コード オペコード (数値) の集まりであり、オペレーティング システムは、これらを読み込んで CPU に解釈および実行を依頼する方法を知っています。そのデータは通常、スタックやヒープ上にはありませんが、オペレーティング システムが配置する「初期化されていないデータ」、「初期化されたデータ」、および「コード」セグメント/領域が混在しています。

于 2014-11-26T09:35:45.587 に答える
1

コンピュータは p と r を決して知りません。変数名は、高級言語で読みやすくするために使用されます。たとえば、次の方法でアセンブリ コードを取得できます。

gcc -S -c code.c

code.s には p と r がまったくありません。

于 2014-11-26T09:41:49.720 に答える