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