2

変数が格納されている場所 (スタック、ヒープ、静的メモリ) を理解するのを手伝ってくれませんか。どうすれば特定できますか?直感的ではありませんが、何がどこにあるのかを画面に表示したいと思います。出来ますか?

これまでのところ、変数のアドレスを出力して、変数が格納されている場所を調べようとしました。しかし、それは私に多くを与えませんでした。ご覧いただき、アドバイスをいただけないでしょうか。私が間違いを犯した場合 (プログラムへの私のコメントを参照してください)、それについて教えてください。

#include "stdafx.h"
#include <iostream>
using namespace std;

int * p1 = new int [3]; // Static memory as it is a global array;
namespace P {int * p2 = new int[3];} // Static memory as it is a namespace; 
namespace {int * p3 = new int[3];} // Static memory as it is a namespace;
using namespace P;

int _tmain(int argc, _TCHAR* argv[])
{
    int * p4 = new int[3]; // Heap as there is a new operator.
    static int * p5 = new int [3]; // Static memory as the variable is static.

    cout << "p1: "<< p1 << endl;
    cout << "p2: "<< p2 << endl;
    cout << "p3: "<< p3 << endl;
    cout << "p4: "<< p4 << endl;
    cout << "p5: "<< p5 << endl;
    cout << endl; 
    cout << "p5 - p4: " << p5 - p4 << endl;
    cout << "p4 - p3: " << p5 - p4 << endl;
    cout << "p3 - p2: " << p5 - p4 << endl;
    cout << "p2 - p1: " << p5 - p4 << endl;

    system("pause");
}
4

2 に答える 2

11

特定の変数に使用されるストレージは、コンパイラの実装の詳細です。コンパイラの実装は、変数の有効期間の最小要件が満たされている限り、選択したストレージ メカニズムを使用する権利の範囲内です。

3 つの一般的なストレージ領域を特定しました。動的に割り当てられた長期ストア (別名「ヒープ」)、動的に割り当てられた短期ストア (別名「スタック」)、および静的に割り振られた長期ストア (別名) です。 「静的メモリ」。レジスタを省略しました。何らかの理由で誰もが常にレジスターを省略します。そしてもちろん、ヒープが 1 つあるという考えはナンセンスです。多くのヒープが存在する可能性があり、それぞれに独自の動的割り当て戦略があります。

変数とは、値を格納する格納場所を指します。変数が存在する場所は、その作成方法によって異なります。ヒープからメモリを割り当てることによって作成される変数は、明らかにヒープ上にあります。静的変数など、長寿命でサイズがわかっている変数は、通常、静的メモリから割り当てられます。実装の詳細として、そのメモリは一部のヒープから割り当てられる可能性がありますが、コンパイラはそうする必要はありません。

有効期間が短いローカル変数は興味深いものです。これらは、コンパイラの気まぐれで、スタックまたはレジスタに割り当てることができます。明らかに、ローカル変数のアドレスを取得すると、レジスタにはアドレスがないため、登録できません。

あなたの特定の例では、20 個の変数を作成しました。p1、、および静的メモリから割り当てられる可能性がありますp2。あなたは の住所を取得したことがないので、登録されている可能性があります。登録されていない場合は、おそらくスタック上にあります。他のすべての変数 ( 、、、... ) は、明示的にヒープに割り当てたため、ヒープに割り当てられます。p3p5p4p4p1[0]p1[1]p1[2]

それは理にかなっていますか?

于 2013-01-18T16:40:14.297 に答える
2

ここではポインタのみが静的です。それが指すものは「ヒープ」にあります。つまり、動的に割り当てられ、呼び出し元が割り当て解除を処理する必要があります。データが実際にどこにあるかは別の問題です。それは、プラットフォームと、何を行うようnewに定義されているかによって異なります。

static int * p5 = new int [3]; 

この GotWを見てください。コメントに投稿してくれた @AlokSave に感謝します。

于 2013-01-18T16:29:34.443 に答える