Я довольно новичок в 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
содержимое копируется в новую область поверх последней пластины или создается какой-то указатель?