Ваша переменная d
обычно не выталкивается из стека. Фигурные скобки не обозначают кадр стека. В противном случае вы не сможете сделать что-то вроде этого:
char var = getch();
{
char next_var = var + 1;
use_variable(next_char);
}
Если фигурные скобки вызвали истинный push / pop стека (как вызов функции), то приведенный выше код не будет компилироваться, потому что код внутри фигурных скобок не сможет получить доступ к переменной, var
которая находится за пределами фигурных скобок (точно так же, как вложенные элементы). функция не может напрямую обращаться к переменным в вызывающей функции). Мы знаем, что это не так.
Фигурные скобки просто используются для определения объема. Компилятор будет обрабатывать любой доступ к «внутренней» переменной снаружи вложенных фигурных скобок как недопустимый, и он может повторно использовать эту память для чего-то другого (это зависит от реализации). Тем не менее, он не может быть извлечен из стека, пока не завершится функция включения.
Обновление: вот что говорит C-спецификация . Относительно объектов с автоматическим сроком хранения (раздел 6.4.2):
Для объекта, у которого нет типа массива переменной длины, его время жизни продолжается от входа в блок, с которым он связан, до тех пор, пока выполнение этого блока не закончится.
В этом же разделе термин «время жизни» определяется как (выделено мной):
Время жизни объекта - это часть выполнения программы, в течение которой для него гарантированно хранится память . Объект существует, имеет постоянный адрес и сохраняет свое последнее сохраненное значение в течение всего срока его службы. Если на объект ссылаются вне его времени жизни, поведение не определено.
Ключевое слово здесь, конечно, «гарантировано». Как только вы покидаете область действия внутреннего набора фигурных скобок, время жизни массива заканчивается. Хранилище может выделяться или не выделяться для него (ваш компилятор может повторно использовать пространство для чего-то другого), но любые попытки доступа к массиву вызывают неопределенное поведение и приводят к непредсказуемым результатам.
В спецификации C нет понятия стековых фреймов. Он говорит только о том, как будет вести себя результирующая программа, и оставляет детали реализации компилятору (в конце концов, реализация будет выглядеть совершенно иначе на CPU без стека, чем на CPU с аппаратным стеком). В спецификации C нет ничего, что указывало бы, где кадр стека закончится или не закончится. Единственный реальный способ узнать это - скомпилировать код на вашем конкретном компиляторе / платформе и изучить получившуюся сборку. Текущий набор параметров оптимизации вашего компилятора, вероятно, также сыграет в этом свою роль.
Если вы хотите убедиться, что массив d
больше не потребляет память во время работы вашего кода, вы можете либо преобразовать код в фигурных скобках в отдельную функцию, либо явно malloc
и free
в память вместо использования автоматического хранения.