The question is to determine programmatically whether stack and heap grows up or down in memory.
As for stack, one way is to declare two variables in the function and list their addresses. If the first variable’s address is greater than or less than that of second’s. But we cannot make sure that the compiler allocates the variables in the order they were declared.
So, an improvement over that is to see the addresses of the passed parameters and the local variables. This solution assumes that the caller would allocate space for the parameters and then calls the function in which case we can determine whether the stack is growing up or down. But in some cases the ompiler may not ensure that calling parameters are allocated first.
The last option (as far as I know, programmatically) is to know the address of a local variable of a called function from a calling function and comparing it with the address of a calling function’s local variable. We can be reasonably sure that the variables in a called function is allocated after the calling function’s variable are allocated.
As for heap, it is dependent on the memory manager’s implementation. If we some how know the unit of allocation for the memory manager, then we can allocate two such units of memory and see their addresses. But even then, it might happen that due to fragmentation, the memory that is allocated afterwards may get a lower memory address which is then bound to misinterpretation. So for, heap I think we cannot deterministically find out.