Now when p is defined inside the function func it would define at the Stak pointer. Thus all variables declared inside func are declared in stack.

Just before func returns, it decreases the Stack pointer and then jumps back to that original return address making variables out of scope for func. If you access the memory location the values would still be persistent but they would not have any reference and can be over written by variables defined in the called function.

Heap memory

Heap consists of memory that can be allocated at run time and its something like a pool of memory from which you can request some chunk of it. It is independent of the function making a request and as your program does not take care of cleaning it up it's the programmer's job to deal with heap memory. The size of objects allocated on the heap is often not known to the compiler - therefore the programmer must allocate and release the memory specifically.