Ваша змінна d
зазвичай не вискакує зі стека. Фігурні дужки не позначають рамку стека. Інакше ви не зможете зробити щось подібне:
char var = getch();
{
char next_var = var + 1;
use_variable(next_char);
}
Якщо фігурні дужки викликали справжній натиск / поп стека (як і виклик функції), то наведений вище код не буде компілюватися, оскільки код усередині брекетів не зможе отримати доступ до змінної, var
яка живе поза дужками (подібно до суб- функція не може безпосередньо отримати доступ до змінних у викличній функції). Ми знаємо, що це не так.
Кучеряві брекети просто використовуються для обстеження. Компілятор розглядає будь-який доступ до "внутрішньої" змінної ззовні додаючих дужок як недійсний, і може повторно використовувати цю пам'ять для чогось іншого (це залежить від реалізації). Однак він може не вискочити з стека, поки функція, що додає, повернеться.
Оновлення: Ось, що має сказати специфікація C Щодо об'єктів з автоматичною тривалістю зберігання (розділ 6.4.2):
Для об’єкта, який не має типу масиву змінної довжини, його термін експлуатації продовжується від вступу до блоку, з яким він пов'язаний, поки виконання цього блоку все-таки не закінчиться.
Цей же розділ визначає термін "термін експлуатації" як (моє наголос):
Термін експлуатації об'єкта - це частина виконання програми, під час якої гарантовано зберігання для неї. Об'єкт існує, має постійну адресу і зберігає своє останнє збережене значення протягом усього життя. Якщо об’єкт посилається поза його життя, поведінка не визначена.
Ключове слово тут, звичайно, "гарантоване". Після того, як ви покинете область внутрішнього набору брекетів, термін служби масиву закінчився. Зберігання може або не може все ще виділятися для нього (ваш компілятор може повторно використовувати простір для чогось іншого), але будь-які спроби отримати доступ до масиву викликають невизначене поведінку та приводять до непередбачуваних результатів.
Специфікація C не має поняття стекових фреймів. Він говорить лише про те, як буде вести себе результуюча програма, а деталі реалізації залишає компілятору (зрештою, реалізація виглядала б зовсім інакше на нестабільному процесорі, ніж на процесорі з апаратним стеком). У специфікації C немає нічого, що мандатує там, де рамка стека закінчиться чи не закінчиться. Єдиний реальний спосіб знати - скласти код на вашому конкретному компіляторі / платформі та вивчити отриману збірку. Поточний набір варіантів оптимізації вашого компілятора, ймовірно, також буде грати роль у цьому.
Якщо ви хочете переконатися, що масив d
більше не з’їдає пам'ять під час роботи вашого коду, ви можете або перетворити код у фігурних дужках в окрему функцію, або явно, malloc
і free
пам'ять замість автоматичного зберігання.