There is a good question here:
"how does it assure there is no
conflict between stack allocation and
heap allocation?"
There is a single contiguous address space in almost all C/C++ implementations, so the stack and heap allocated memory do have to coexist in that space.
Although each time the stack grows and shrinks this is not done with individual heap allocations, you can still think of the stack as a single large block of memory allocated from the heap. If the stack grows beyond the boundary of that block, then we have a stack overflow (catchy name... someone should name a website after it).
In a multi-threaded program, each time a thread starts, a new stack has to be allocated for it, and when a thread dies the stack can be deallocated. And it would make sense for those whole-stack blocks to be allocated using the same heap management as is exposed through malloc
/free
.
So - very approximately speaking - you can think of the stack as being a type of object that coexists in the heap. A whole stack is malloc
-ed all in one go, when a thread starts up, and then it gets suballocated from, and then it gets free
-d in one go.
On Windows, you can (if you like to live dangerously) call the same virtual memory APIs yourself to find out about the stack and to force virtual page within it to be freed.