With C++ (and C before it) all variables are stack based, unless they are directly allocated from the heap with a malloc (old style) or new (preferable) - in which case you must use the appropriate delete or free method when you are finished with it.
There is no such thing as "dynamic" variables on the stack, since the variable space a function used can be calculated at compile time - dynamic allocation only happens with the heap.
Stack based variables are automatically deallocated when the function exits, because the stack is then freed for the next function to use it:
Maybe a little diagram will help: "x" is used stack, "f" is free. "sp" is the stack pointer - the next free memory
Stack before function call:
xxxxxxxxffffffffffffffff
sp------^
Call function
xxxxxxxxRfffffffffffffff
sp-------^
Now, the Return address has been stacked ("R" - the place in your code from which the function was called) and the sp has moved to the next free location
In function with variables
xxxxxxxxRVVVVfffffffffff
sp-----------^
The variables have been allocated on the stack ("V" and the sp moved)
After function
xxxxxxxxrvvvvfffffffffff
sp------^
The sp has moved back before the return address and all the variables have been deallocated - but not changed in memory, which is why I changed them to lower case.
When the next function is called, the same process happens and the memory is re-used.
That is why hanging references are a PITA - if you return a pointer to a stack based variable, it is still a valid pointer, and teh memory will work - but it can also be used for something else and you end up corrupting memory.