Program memory layout in linux

if I have an array allocated on the stack a pointer to the first element will also be lower > in value than a pointer to the second element ?

It is not important "how" you allocate the array, you can increase or decrease the stack pointer, but as result you have address space reserved for the array.

You can work with them in normal way, since the lowest adress is reserved for element 0.

so my question is what is the correct memory layout for a process in Linux ?

You can check it yourself. Insert somewhere into you program something like std::cin.get() to pause your program.

Then run in a separate shell:

ps aux | grep your_program_name
cat /proc/<pid show by grep>/maps 

This prints the memory mappings of your process, where you can see where the heap, the stack and other things are placed in memory.

About the stack: let's assume that you have ordinary machine with Linux and Intel or AMD 64 bit CPU. Then write the following code:

extern void f(int);

void g(int param)
{
    f(param);
}

compile it and disassemble:

g++ -ggdb -c test_my_stack.cc  && objdump -S test_my_stack.o

you can see (unimportant details removed):

 void g(int param)
 {
 0:   55                      push   %rbp
 1:   48 89 e5                mov    %rsp,%rbp
 4:   48 83 ec 10             sub    $0x10,%rsp
 8:   89 7d fc                mov    %edi,-0x4(%rbp)
    f(param);
 b:   8b 45 fc                mov    -0x4(%rbp),%eax

as you can see in sub $0x10,%rsp we reserved space in the stack by decreasing (moving down) the stack pointer.


First thing that bothered me with that image is that if the heap grew from high to low then if I allocated an array on the heap shouldn't a pointer to the second element be smaller in int value than a pointer to the first element ? which would be confusing

Not at all. Let's say you allocate an array of 10 bytes from a pool of memory that grows from high to low. All the allocator would have to do is decrement the "bottom" of that pool of memory by 10, then use that value as the start of the allocated array. The array would then end at the old "bottom". Pointer arithmetic would still work as expected, but you would "grow" towards low address.