Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I see a lot of partial answers but no complete answer. Here's that picture you posted again:</p> <p><img src="https://i.stack.imgur.com/1aV6B.png" alt="simplified image of virtual memory layout"></p> <p>The "break"--the address manipulated by <code>brk</code> and <code>sbrk</code>--is the dotted line at the top of the <em>heap</em>. The documentation you've read describes this as the end of the "data segment" because in traditional (pre-shared-libraries, pre-<code>mmap</code>) Unix the data segment was continuous with the heap; before program start, the kernel would load the "text" and "data" blocks into RAM starting at address zero (actually a little above address zero, so that the NULL pointer genuinely didn't point to anything) and set the break address to the end of the data segment. The first call to <code>malloc</code> would then use <code>sbrk</code> to move the break up and create the heap <em>in between</em> the top of the data segment and the new, higher break address, as shown in the diagram, and subsequent use of <code>malloc</code> would use it to make the heap bigger as necessary.</p> <p>Meantime, the stack starts at the top of memory and grows down. The stack doesn't need explicit system calls to make it bigger; either it starts off with as much RAM allocated to it as it can ever have (this was the traditional approach) or there is a region of reserved addresses below the stack, to which the kernel automatically allocates RAM when it notices an attempt to write there (this is the modern approach). Either way, there may or may not be a "guard" region at the bottom of the address space that can be used for stack. If this region exists (all modern systems do this) it is permanently unmapped; if <em>either</em> the stack or the heap tries to grow into it, you get a segmentation fault. Traditionally, though, the kernel made no attempt to enforce a boundary; the stack could grow into the heap, or the heap could grow into the stack, and either way they would scribble over each other's data and the program would crash. If you were very lucky it would crash immediately.</p> <p>I'm not sure where the number 512GB in this diagram comes from. It implies a 64-bit virtual address space, which is inconsistent with the very simple memory map you have there. A real 64-bit address space looks more like this:</p> <p><img src="https://i.stack.imgur.com/RQxMY.png" alt="less simplified address space"></p> <p>This is not remotely to scale, and it shouldn't be interpreted as exactly how any given OS does stuff (after I drew it I discovered that Linux actually puts the executable much closer to address zero than I thought it did, and the shared libraries at surprisingly high addresses). The black regions of this diagram are unmapped -- any access causes an immediate segfault -- and they are <em>gigantic</em> relative to the gray areas. The light-gray regions are the program and its shared libraries (there can be dozens of shared libraries); each has an <em>independent</em> text and data segment (and "bss" segment, which also contains global data but is initialized to all-bits-zero rather than taking up space in the executable or library on disk). The heap is no longer necessarily continous with the executable's data segment -- I drew it that way, but it looks like Linux, at least, doesn't do that. The stack is no longer pegged to the top of the virtual address space, and the distance between the heap and the stack is so enormous that you don't have to worry about crossing it.</p> <p>The break is still the upper limit of the heap. However, what I didn't show is that there could be dozens of independent allocations of memory off there in the black somewhere, made with <code>mmap</code> instead of <code>brk</code>. (The OS will try to keep these far away from the <code>brk</code> area so they don't collide.)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload