As mentioned already, sizes are OS specific. For e.g. on windows using Visual Studio, default stack size is 1MB
msdn
On Linux the following command can show show your current one.
ulimit -s or -a
On my Linux mint 64 bit it shows 8192 KB.
Every program when loaded in memory has several segments. In assembly one can indicate each of those using .data, .code etc prefix (intelx86).
It is data segment which has several sub sections. Both stack and heap are part of it in addition to several others.
Stack can also grow implicitly i.e. when you make another function call, an activation record is pushed on to stack, they by utilizing more memory of stack. That is why infinite recursion results in crash when a program runs out of allocated stack.
When a function call returns, that activation record is popped and stack shrinks.
In contrast heap grows from the opposite direction and contains all dynamically allocated memory.
The reason these two segments grow in opposite direction is to maximize the utilization of their combined memory. Note that as mentioned in comments this is not a c standard, but most common OS's have this implemented.
------ stack starts ----------- stack grows downward
-------- Unless they cross each other a program is okay to run.
------- heap starts ------------heap grows upwards
If your program uses no heap, your stack can utilize maximum memory including that of heap too. If program makes few recursive calls and uses minimum local variables (i.e. uses less memory for stack), it can utilize heap to the most.
Other parts of data segment are BSS etc. which might contain fields such as uninitialized static variables