Когда создается стек вызовов (call stack) в программе?

«Когда создается стек вызовов (call stack) в программе?» — вопрос из категории Алгоритмы и структуры данных, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Стек вызовов (call stack) — это структура данных, управляемая системой во время выполнения программы. Он создается и поддерживается автоматически.

Когда это происходит:

  1. При запуске потока: Каждый поток имеет свой собственный стек.
  2. При вызове функции/метода: Для каждого вызова в стек помещается стековый фрейм (stack frame), который содержит:
    • Локальные переменные функции.
    • Аргументы, переданные в функцию.
    • Адрес возврата (куда передать управление после завершения функции).

Пример работы стека:

func functionA() {
    let a = 10 // Локальная переменная помещается в стековый фрейм functionA
    functionB(param: a)
}

func functionB(param: Int) {
    let b = param * 2 // Локальная переменная помещается в стековый фрейм functionB
    print(b)
}

functionA() // Запускает цепочку вызовов

Порядок операций в стеке (LIFO - Last In, First Out):

  1. Вызывается functionA() – создается её фрейм.
  2. Внутри functionA вызывается functionB() – поверх фрейма A создается фрейм B.
  3. functionB завершается – её фрейм удаляется из стека.
  4. functionA завершается – её фрейм удаляется из стека.

Важные ограничения:

  • Размер стека ограничен. Глубокая рекурсия может вызвать переполнение стека (stack overflow).
  • Память в стеке выделяется и освобождается очень быстро.
  • Стек работает независимо от кучи (heap), где хранятся объекты, выделенные динамически.