私は C++ にかなり慣れていないので、スタックとヒープの概念をできる限り (または少なくとも知る必要がある限り) 理解しようとしています。スターターはそれほど気にするべきではないと言う人もいますが、メモリ リークやスタック オーバーフローは非常に簡単に発生するように思えます。私はいくつかのものを読んでいますが、まだ少し混乱しており、それが正しいかどうか確信が持てません.
これが私がこれまでに得たものです...
1. ヒープ:
ヒープは、動的に割り当てられる共有領域です。適切なポインターとコンテンツ (タイプと長さ) の知識があれば、プロセスのどの部分からでもアクセスできます。間違ったポインター (単純なアドレスまたは割り当て解除へのポインター) を使用しようとすると、セグメンテーション違反が発生します。割り当てられたものよりも大きなコンテンツにアクセスすると、セグメンテーション違反が発生します (たとえば、割り当てられたものよりも大きな配列を読み取ろうとするなど)。未使用の領域は、メモリリークを避けるために「手動で」割り当てを解除する必要があります
2.スタック:
スタックは、パラメーターとローカル変数が割り当てられるメモリの一部です。スタックのサイズには制限があります。スタックは LIFO (Last In First Out) として機能します。
スタックが事前定義されたサイズ (スタック サイズ) のビンであるとしましょう。ローカル変数を定義すると、それらはスタック (ビン) に置かれ、スコープが変更されるとすぐに (関数が呼び出されるなど)、プラッターがビンで使用され、以前のスコープで定義された変数と新しいローカル変数へのアクセスが防止されます。スコープが作成されます。関数が終了すると、すべてのローカル変数が破棄され、ビン内のプラッターが削除されます (以前のスコープに戻ります)。
例 :
void MyFunction()
{
int *HeapArray = new int[10];
// HeapArray is assigned 40 bytes from the heap
// *HeapArray is assigned 4 bytes from the stack in a 32 bit environment
int StackArray1[10];
// StackArray is assigned 40 bytes from the stack
int StackArray2[20];
// StackArray is assigned 80 bytes from the stack
HeapArray = StackArray2;
// segmentation fault because StackArray it too large
delete HeapArray;
// this will deallocate the area assigned in the heap
// omitting delete would result in memory leaks
// the pointer itself *HeapArray continues to exist in the stack
HeapArray = StackArray1;
// segmentation fault because HeapArray is pointing to deallocated memory
MyFunction();
// this will result in a stack overflow
}
質問:
Q1. スタックに対して大きすぎるローカル変数を定義したり、上記の例のように無限再帰関数を使用したりすると、セグメンテーション違反が発生します。これが「スタック オーバーフロー」と言っていないのはなぜですか? スタックが「ヒープにオーバーフロー」してセグメンテーション違反を引き起こしているためですか?
Q2. スタックに指定したビンとプラッターの例を想定すると、使用時にextern
、コンテンツは最後のプラッターの上にある新しいスコープにコピーされますか、それとも何らかのポインターが作成されますか?