the addresses in memory starts from highest to lowest
Are the addresses of the houses on your street ordered from highest to lowest, or from lowest to highest? Well, that depends on which way you're driving.
Just like postal addresses, memory addresses aren't really ordered at all. Each address simply identifies a unique location in memory (At least conceptually. We'll ignore, for a moment, segmented or virtual memory).
But when your mail carrier delivers the daily mail, he most likely does work in either highest-to-lowest or lowest-to-highest order (probably both, down one side of the street, and up the other side). This is more efficient, of course, than jumping from house to house at random. In addition, it makes the carrier's job much simpler. If he were to jump from house to house in a random order, it would be difficult to keep track of which houses he had already visited, and which ones still needed delivery. If he simply goes in order, then the position of his truck is all he needs to keep track of.
A stack is similar to this. It doesn't occupy arbitrary positions in memory, but instead has a first position, and subsequent positions follow in logical order from there. In this way, a stack pointer (often "SP") is all that is needed to keep track of which stack locations are occupied and which are free.
A heap is necessarily different, though. While a stack inherently has a first-in-last-out ordering, a heap is inherently unordered. Heap memory can be allocated and deallocated at any time. Earlier allocations can outlive later allocations. A heap, therefore, must be able to allocate arbitrary address ranges, and has to keep track of them all.
Because of the different ways in which the stack and heap operate, they should occupy different areas of memory. In your example, a second stack allocation would overwrite memory occupied by your heap allocation. Obviously, this would be a bad thing, and is what is referred to as a stack overflow.
Most modern CPUs have all the features necessary to keep stack memory and heap memory completely separate. This is where memory segments and virtual memory come into play. On some platforms, the stack and the heap may be identified by the same address range, while still occupying different areas of physical memory or even secondary storage. A discussion of how this works it outside the scope of this post.
Most modern operating systems don't actually do this, though. More commonly, a "flat" address space is used, where all addresses, whether stack, heap, code, or whatever, refer to the same address space. This makes it easier for the application developer, by obviating the need to juggle segment identifiers for every address.
In a flat address space, the same scheme of separating stack and heap is used that was used in ancient CPUs that had no memory segmentation or virtualization: the stack grows down from the "top" of memory (higher addresses), and the heap grows up from the bottom of memory (lower addresses). A certain point between the two may be picked to be the limit of both, and when one reaches the point, an error condition occurs—either stack overflow or out of memory.
Of course, this description is a huge simplification, but hopefully it gives a better basic understanding.