int globalInt = 1;
int main(){
int* heapInt = new int(1);
}
globalInt と heapInt の違いは何ですか? heapInt が指しているものがヒープ内にあること、globalInt が何らかのグローバル データ ストレージに入ることがわかっていますが、違いは何ですか? なぜ一方を他方に使用するのですか?
よろしくお願いします。
int globalInt = 1;
int main(){
int* heapInt = new int(1);
}
globalInt と heapInt の違いは何ですか? heapInt が指しているものがヒープ内にあること、globalInt が何らかのグローバル データ ストレージに入ることがわかっていますが、違いは何ですか? なぜ一方を他方に使用するのですか?
よろしくお願いします。
グローバル変数には静的な保存期間があります。これは、オブジェクトがプログラムの開始から終了まで存在することを意味します。プログラムの全期間にわたって存在します。
new-expression で作成されたint
には、動的な保存期間があります。その寿命は new-expression で始まり、そうすると終了しますdelete heapInt;
。
これら 2 つの保存期間は、スペクトルの両端にあると考えることができます。グローバル変数は常に存在するため、その有効期間を最小限に制御できます。動的に割り当てられたオブジェクトは、コード内の任意の場所で作成および破棄できるため、ほとんどの制御が可能です。
グローバル変数には名前があることにも注意してください。これにより、その名前がスコープ内にあるコードのすべての部分からオブジェクトにアクセスできるようになります。対照的に、動的に割り当てられたオブジェクトにアクセスするには、そのオブジェクトへのポインターが与えられている必要があります。
グローバル変数は、プログラムにグローバル状態を導入するため、一般的に悪い習慣と見なされます。つまり、グローバル変数を変更または使用する関数が、そのインターフェイスでそれを行うことが明確にされていない可能性があります。これは、関数に秘密の副作用がある可能性があることを意味し、テストが困難な予測不可能で保守不可能なコードにつながります。
一方、動的に割り当てられたオブジェクトはしばしば必要になりますが、慎重に使用する必要があります。オブジェクトの有効期間が適切に管理されていることを確認することが重要です。これに対する 1 つのアプローチはRAIIを使用することです。この場合、オブジェクトはコンストラクターでのみ動的に割り当てられ、それに応じてデストラクタで破棄されます。追加の最新のアプローチは、メモリ管理を完全に自分で行うことを避け、代わりにスマート ポインターを使用することです。
麺を焼くためだけに、あなたも考えましたか
int globalInt = 1;
int* globalHeapInt = new int(1);
int main() {
int* heapInt = new int(1);
}
理由の部分に答えるには: ヒープに何かを格納すると、ポインターのオーバーヘッドが発生します。構築するビット数に応じて、4 または 8 バイトです。
プレーン データ型の globalInt などのグローバル値は、実行可能ファイルの「データ セグメント」に書き出され、OS がアプリケーションを起動するときに、プロセスに組み込まれて読み込まれます。
globalHeapInt は NULL の値でロードされ、コンパイラによって提供される秘密のブートストラップ「プリメイン」コードで、プログラムを実行する必要があります。
globalHeapInt = malloc(sizeof(int));
*globalHeapInt = 1;
64 ビット システムでは、4 バイトの値を格納するために (少なくとも) 12 バイトを使用しています。
「heapInt」も同様の処理を実行しますが、ポインタはスタックまたはレジスタに格納されます。
グローバル値を使用する理由は何ですか? 有限の既知の量のデータがある場合、それらを単純なグローバルに含めることは理にかなっています。
したがって、主にヒープは動的ストレージ用です-まだ必要かどうか、またはどれだけ必要かが事前にわからない場合。たとえば、書籍のリストをコマンド パラメーターとして受け取るプログラムを想像してください。
// reserve memory for upto 1000 Books.
Book globalBooks[1000];
// or use the heap when we know how many we need.
int main(int argc, const char* argv[])
{
int numBooks = argc;
if ( numBooks < 1 ) {
printf("Screw you and your empty book list.\n");
exit(1);
}
Books* heapBooks = new Books(numBooks);
...
}
最初のフォームは 1000 冊しか扱えませんが、常に 1000 冊までのメモリを持っています。2 番目の形式では、プロセスで使用できるメモリの最大量まで、任意の数のブックを処理できます。