Reputation: 750
When I read about Stack and Heap for example on this page,
I had one question, if, like in the example given on the page, a functions puts all its local variables on the stack, does the stack actually access the different variables?
Because a stack normally only can access the top, it would only be able to access ONE variable of the function.
Does this imply that variables of a function are stored in a struct on the stack?
Upvotes: 8
Views: 3083
Reputation: 23780
A stack frame consists of several elements, including:
- Return address
The address in the program where the function is to return upon completion
- Storage for local data
Memory allocated for local variables
- Storage for parameters
Memory allocated for the function’s parameters
- Stack and base pointers
Pointers used by the runtime system to manage the stack
A stack pointer usually points to the top of the stack. A stack base pointer (frame pointer) is often present and points to an address within the stack frame, such as the return address. This pointer assists in accessing the stack frame’s elements. Neither of these pointers are C pointers. They are addresses used by the runtime system to manage the program stack. If the runtime system is implemented in C, then these pointers may be real C pointers.
Upvotes: 3
Reputation: 35219
You have a little confusion about data organization and access. In stack memory is organized in such a way that new data can be added or removed only from the "top". This however has nothing to do with restrictions about accessing other elements. Such restrictions can be present in some logical stack implementations (like std::stack
from C++ STL), but they are not mandatory.
Hardware stack is really more like a fixed size array, with variable array start location (stack pointer), so other elements can be accessed by indexing stack pointer. The difference from "standard" array is that it can contain elements of different size.
Upvotes: 3
Reputation: 156
What you want to know is how stack frames work.
To use a stack frame you have to have several registers pointing to several "points of interest" on said stack frame and modify them or use an offset of where they are pointing. An example would be:
main()
is about to call foo()
. The base of main()
is pointed to by the "base pointer" register EBP. Until now, main()
has been using all the registers for its own stack frame. Now it will need to save the contents of those registers if it is to use them again after the call. After the call, foo()
will (among other things) set up its own stack frame by allocating memory for its local variables, setting the "stack pointing" register called ESP to the top of its stack frame while saving the address of the main()
base pointer and by copying the contents of the "next instruction" register called EIP so that it knows where to return after its completion. The stack frame of foo()
is now on top of the stack frame of main()
and the stack looks something like this:
[Registers that
foo()
saved.][Local variables of
foo()
.][
main()
base pointer address. EBP points here and will point to the address stored here afterfoo()
is done.][
main()
return address (foo()
will return to where this address is pointing.)][Arguments for
foo()
.][Registers that
main()
saved.][...]
As you can see, we can access both the arguments of foo()
as well as its local variables as simple offsets from where the EBP register points. If the first local variable is 4 bytes long we are going to find it at EBP - 4 for example.
Upvotes: 1
Reputation: 409166
The stack-pointer is, like its name implies, a pointer like any other, and it points to normal standard memory. To access any area of the stack you simple add an offset to the pointer.
If you think of it in terms of C pointers, you have the stack pointer
char *stack_pointer = some_memory;
This pointer can then be used as a normal pointer, including adding offsets to access specific locations on the stack, like e.g.
*(int *)(stack_pointer + 4) = 5;
I recommend you try to learn assembler code, then you can make a very simple program, with a few local variables, and compile it to assembler code and read it to see exactly how it works.
Upvotes: 9
Reputation: 20842
There is often confusion between stack semantics
vs stack region
(or storage area). Same
goes for heap. As well, the proliferation of "stack based virtual machines like JVM and CLR" mislead non-C and C++ programmers into thinking the native runtime stack works the same way.
It is important to differentiate:
Stacks on most architectures provide random access semantics of O(1)
. The common
example is the immediate and base+offset addressing modes and the stack and base pointers in x86.
The actual stack area is allocated in a LIFO fashion, but the individual variables are
random accessible, O(1)
. If you wanted the stack to be gigantic, it could be.
Space is allocated like a LIFO stack. Variables are accessed within the stack like an array/vector or by an absolute address (pointer).
So, no, in C and C++, you aren't limited to a single variable at a time.
Upvotes: 7