The values are "erased" in the same way that data is "erased" from your hard drive when you delete it. The data is still there, but you lose your ability to reference that data; as a result, it is effectively gone. We don't completely erase the data from the stack (or from disk, unless you are doing a low level format) because it is much faster to simply stop referencing data than it is to explicitly set that data to 0 (or some other invalid value).
Let's pretend you have a simple program:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
int GetValue(int seed)
{
srand(seed);
int random = rand();
return random;
}
int main(int argc, char** argv)
{
GetValue(5);
return 0;
}
| |
If you were to insert a breakpoint at line 4 of that program (
int random= rand();), you might have a stack that looks something like this (this is a simplification for demonstration purposes):
1 2 3 4 5 6 7
|
Stack Pointer is Here
0x14 - (4 bytes representing the current value of int random in function GetValue())
0x10 - (4 bytes representing the current value of parameter int seed to function GetValue())
0xC - (4 bytes representing the address of the GetValue(5) call in int main() - you need this address in order to set your Program Counter back to the appropriate executing statement when GetValue() returns)
0x8 - (4 bytes representing the current value of parameter int argc to function main())
0x4 - ... more data representing the state of function main() continues...
| |
In conjunction with this stack, you will also have a Stack Pointer. The Stack Pointer indicates where the currently active stack resides. In the above example, with your breakpoint inside the GetValue() function, you would have a Stack Pointer of 0x14.
Now let's pretend we let the breakpoint continue, and we reach the line that returns from GetValue(). This "pops" the stack, giving us a new Stack Pointer down at 0x8 (where the data for function int main() began). If you were to examine the stack at this point, it would still look exactly the same... just your Stack Pointer is in a different place.
1 2 3 4 5 6 7 8
|
0x14 - (4 bytes representing the current value of int random in function GetValue())
0x10 - (4 bytes representing the current value of parameter int seed to function GetValue())
0xC - (4 bytes representing the address of the GetValue(5) call in int main() - you need this address in order to set your Program Counter back to the appropriate executing statement when GetValue() returns)
Stack Pointer is Here
0x8 - (4 bytes representing the current value of parameter int argc to function main())
0x4 - ... more data representing the state of function main() continues...
| |
If you were to then invoke GetValue() a second time, those values would again start writing at 0xC, 0x10, and 0x14... overwriting the values from the previous invocation. However, until you actively do something which causes those values to be overwritten... they still exist on the stack; your Stack Pointer, however, no longer includes them.
Hope that was clear!
-Thinias