Variables on the stack
لم يُترجم بعد؛ يُعرض باللغة الإنجليزية
Every time a function runs, its local variables need somewhere to live. C++ gives each call a stack frame: a block of memory pushed on top of the call stack when the function starts and popped off when it returns. Step through a ten-line program, watch main's frame appear, a call to square push a second frame on top, values get copied in and out, and the frames disappear again, automatically.
5 أسئلة سريعة
اختر إجابة لتعرف السبب. تُحفَظ نتيجتك مع تقدّمك.
01What is stored in a function's stack frame?
A frame holds the local variables of one running call, including its parameters. Each call gets its own frame, so two calls never share local variables.
02In the program, square(a) runs and then returns. What happens to x and y?
Local variables have automatic storage duration: they are destroyed at the end of their block. When square returns, its whole frame is popped and x and y are gone, with no clean-up code from you.
03Inside square, suppose you add the line x = 100;. What is a in main afterwards?
x was initialised with a copy of a (passing by value). x and a are separate slots in separate frames, so changing x leaves a at 3.
04Why is creating local variables on the stack so fast?
A call reserves its frame by moving one marker, the stack pointer, and a return gives it back the same way. There is no search for free space, because each frame's size is fixed at compile time.
05Which of these is a bug?
When the function returns, its frame is popped, so a pointer or reference to one of its locals points at memory that no longer holds that variable (a dangling pointer). The C++ Core Guidelines (F.43) forbid it. Returning a copy is fine.
المسرد
- Local variable
- A variable declared inside a function or block. Its name works only inside that block, and it lives until the block ends.
- Call stack
- The memory a running program uses for the functions that are currently running: one frame per call, newest on top.
- Stack frame
- The block of stack memory for one function call: its parameters and local variables (plus bookkeeping such as where to return to).
- Push / pop
- Adding a frame on top of the stack when a function is called, and removing it when the function returns.
- Automatic storage duration
- The C++ standard's name for how local variables live: created when their block starts, destroyed automatically when it ends.
- Pass by value
- Calling a function with a copy of the argument: the parameter is a new variable, so changing it never changes the caller's variable.
- Stack pointer
- A CPU register that marks the top of the stack. Moving it up or down is how frames are pushed and popped.
- Stack overflow
- A crash caused by using more stack memory than the system allows, for example through very deep recursion or huge local arrays.
الملاحظات والمصادر
- The C++ standard does not use the word stack: it says local variables have automatic storage duration, created when their block starts and destroyed when it ends. Every mainstream compiler keeps them in a call stack, though the optimiser may keep some only in CPU registers.
- The figure piles frames upward, like plates. In real memory the stack on x86-64 and ARM grows toward lower addresses, and a frame also holds the return address and saved registers.
- The ? means no value has been written. Reading an int that was never given a value is undefined behaviour in C++20 (C++26 calls it erroneous behaviour): either way it is a bug, so always initialise local variables.
- Microsoft's linker reserves 1 MB of stack by default (the /STACK option). On Linux and macOS, ulimit -s shows the limit for the main thread.
- The program on the card is real, standard C++. Build it with g++ -std=c++20 -Wall -Wextra square.cpp -o square (or clang++): there are no warnings, and ./square prints 9.
- Before main runs, the C++ runtime's startup code (for example _start and __libc_start_main on Linux) calls it, so a few frames sit below main's. After main returns, that code runs atexit handlers and destructors of static objects, then calls exit. The figure leaves those frames out.
- Strictly, square's frame is released as square returns, after its return value has been made. The figure shows the copy and the pop as two steps so each can be seen.
- cppreference.com: Storage class specifiers (automatic storage duration)
- cppreference.com: Scope
- cppreference.com: Function declaration (parameters)
- cppreference.com: return statement
- cppreference.com: Default-initialization (indeterminate values)
- cppreference.com: Main function
- C++ Core Guidelines (isocpp.org), F.43: Never return a pointer or a reference to a local object
- Standard C++ Foundation (isocpp.org): Freestore management FAQ
- Microsoft Learn: /STACK (Stack allocations)
- Bryant and O'Hallaron, Computer Systems: A Programmer's Perspective, 3rd ed., §3.7 Procedures
اختبار يتاح بعد الخطوة الأخيرة.