Another question you might get is to try to figure out which way a stack grows. As we know a stack (memory region interpreted as a stack) gets allocated for each process. The stack is used to store local variables and context local to the process. Each function call in a process gets a frame inside the stack where the variables local to the functions get stored; when the function exits the frame gets freed. The stack is also used to store the address of the caller function so that the IP (instruction pointer) can jump back after exiting a function call. i.e:
From the example below (Program:) before main() jumps off into foo(), it first pushes the current address of the IP into the stack so that when foo finishes, the IP can know where to go back to in main();
In some systems the stack is said to grow up and in others it is said to grow down. What the heck does that mean? See bellow:
Memory:
0x00000004 -- -- -- --
0x00000008 -- -- -- --
0x0000000C -- -- -- --
0x00000010 -- -- -- --
...
Program:
int foo();
main();
main()-call->foo();
In a simplistic world (don't hold me to the number it's just an example) if your main()'s frame is at 0x0000000C and foo()'s frame is pushed onto the stack at 0x00000008 then the stack is said to grow down-even though in the diagram it might appear as growing up-because the addresses decrease in that direction. If foo() were to appear at 0x00000010 then the stack would grow up, or in the direction in which the addresses increase.
Code:
#include <stdio.h>
void stackTracer(int *x)
{
int y;
if(&y > x)
printf("The stack grows down\n");
else
printf("The stack grows up\n");
}
int main()
{
int x;
stackTracer(&x);
getchar();
return 0;
}
The code works because when stackTracer is called, the main() frame had already been created in the stack, therefore stackStracker() would be pushed onto the stack after main(). If the address of a variable declared in stackTracer() is greater that the address of a variable declared in main(), that tells you that the stack is growing up as it's growing in the direction that the addresses increase.
StackOverflow
The Stack has a size that is defined even before the process begins to run. The size of the Stack is defined by the linker and can be adjusted by changing the linker flags. But once the program has been linked with the Stack size then that will remain the size of the process' stack throughout its life time. Sometimes if you are not careful, you can grow the stack (recursion anyone?) over its allowed size; and you get a stackoverflow exception.
How can you tell the size of your stack?
This program came out of a couple of minutes of spare time when a co-worker friend of mine and myself decided to overflow the stack just for fun:
Code:
#include <stdio.h>
int counter = 0;
void crasher()
{
double array[10];
array[0]=1;
counter++;
printf("Counter is at %d", counter);
crasher();
}
int main()
{
crasher();
return 0;
}
Then to calculate the size of your stack do => counter (amount of times you allocated that array) * 8 bytes (the size of a double [check your system though]) * 10 (the amount of doubles in the array). Note: this will be roughly the size of your stack, to check the exact size you can always check the default for your linker or the linker flags.
No comments:
Post a Comment