всегда ли поддерживается эта линейность, или, например, вызов mmap может выделить память, перекрывающую сегмент данных?
Наблюдаемое поведение состоит в том, что область brk всегда линейна. Детали реализации: Если увеличение области brk невозможно, например, из-за блокирования отображения, glibc переключится на mmap-only. Небольшие выделения (<128 КБ), по-видимому, получаются с помощью glibc через brk, если это возможно, поэтому блокирует это с помощью: </p>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
int main(void)
{
int i;
for (i = 0; i < 1024; ++i) {
malloc(2048);
if (i == 512) {
void *r, *end = sbrk(0);
r = mmap(end, 4096, PROT_NONE,
MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
}
}
}
в стринге даёт действительно
[...]
brk(0x1e7d000) = 0x1e7d000
mmap(0x1e7d000, 4096, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x1e7d000
brk(0x1e9e000) = 0x1e7d000 <-- (!)
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbfd9bc9000