A programmer defines `count = 0` inside function `increment()` and increments it before returning. Every call to `increment()` starts with `count = 0` instead of preserving the previous value. What explains this?
APython automatically resets integer variables to 0 between function calls as a safety measure
BEach call to `increment()` creates a new stack frame with its own fresh `count`, independent of all previous calls
CThe variable is stored on the heap and garbage-collected after each call returns
DLocal variables are shared across all calls to the same function, so `count` should persist — this must be a bug elsewhere
Each function call creates a new stack frame from scratch containing fresh copies of the function's parameters and local variables. When `increment()` is called a second time, a new frame is pushed with `count` initialized to 0 — completely independent of the frame from the first call, which was already popped when that call returned. This is the mechanism behind local variable scope: variables live and die with their stack frame. To persist a value across calls, it must live outside the function (e.g., as a global variable or object attribute).
Question 2 Multiple Choice
During execution, the call sequence is: main() → process() → validate(). Where is the stack frame for process() while validate() is executing?
AAll three frames are on the stack simultaneously: validate() on top, process() in the middle, main() at the bottom
BOnly validate()'s frame is on the stack — process()'s frame was removed when it called validate()
Cprocess() and main() have been removed from the stack since they called other functions before completing
DThe frames are stored in a queue ordered by call time, not a stack
Calling a function pushes a new frame onto the stack; returning pops it. While validate() is running, it has not returned yet, so its frame is on top. process() called validate() and is waiting — process()'s frame remains on the stack below validate()'s. main() called process() and is also still waiting. All three frames exist simultaneously. This is exactly what a stack trace shows when a program crashes: the entire chain of active frames at the moment of the error, reading from the most recent call at the top to the entry point at the bottom.
Question 3 True / False
When function A calls function B, function A's stack frame is temporarily removed from the call stack while B executes, then restored when B returns.
TTrue
FFalse
Answer: False
Function A's frame remains on the stack the entire time B is executing. The call stack is a genuine stack (last-in, first-out): A's frame is pushed first, then B's frame is pushed on top. While B runs, both frames are on the stack simultaneously. When B returns, B's frame is popped — A's frame was never touched. This is how A 'remembers' its local variables and the return address (where to resume execution) after B returns. If frames were removed and restored, local variable preservation would not work.
Question 4 True / False
Each invocation of a function gets its own independent stack frame, even when the same function is called multiple times — including recursively.
TTrue
FFalse
Answer: True
Every function call — regardless of origin — pushes a new, independent stack frame. In recursion, the same function may have many frames on the stack simultaneously, each with its own copy of the local variables at a different stage of the computation. This is why recursion works correctly: each recursive call operates on its own local state without interfering with others. It is also why deep recursion can cause a stack overflow — each frame consumes memory, and the stack has a fixed maximum size.
Question 5 Short Answer
How does the call stack explain why two separate calls to the same function each get their own independent copies of local variables?
Think about your answer, then reveal below.
Model answer: Each function call pushes a new stack frame onto the call stack. That frame contains fresh copies of the function's parameters and local variables, initialized from scratch for that call. When the function returns, the frame is popped and its variables disappear. A second call pushes another new frame — entirely independent of the first. Because the two calls never share a frame, their local variables are completely separate and cannot interfere with each other.
This stack-frame-per-call design is what gives functions their essential property of independent, reproducible behavior. Without it, two calls to the same function would clobber each other's variables — programs would be nearly impossible to reason about. It is also what makes recursion possible: a recursive function calling itself just pushes another frame with new local variables, without disturbing the frames already on the stack from earlier calls. The stack trace you see when a program crashes is literally a readout of every frame currently on the call stack, showing the exact chain of calls that led to the error.