Search code examples
c++memorymallocmmapsbrk

C++ Malloc Doesn't call mmap or brk?


On ubuntu 18.04 I wrote the following c program and ran it with an input of 100

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    int x;
    scanf("%d", &x);
    usleep(1);
    void *tmp = malloc(x);
    usleep(1);
    free(tmp);
    return 0;
}

The output in terminal was: (with strace)

strace ./a.out
execve("./a.out", ["./a.out"], 0x7ffd69236c10 /* 50 vars */) = 0
brk(NULL)                               = 0x55a719717000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=96020, ...}) = 0
mmap(NULL, 96020, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7acb879000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\35\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030928, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7acb877000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7acb277000
mprotect(0x7f7acb45e000, 2097152, PROT_NONE) = 0
mmap(0x7f7acb65e000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f7acb65e000
mmap(0x7f7acb664000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7acb664000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7f7acb8784c0) = 0
mprotect(0x7f7acb65e000, 16384, PROT_READ) = 0
mprotect(0x55a718d34000, 4096, PROT_READ) = 0
mprotect(0x7f7acb891000, 4096, PROT_READ) = 0
munmap(0x7f7acb879000, 96020)           = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
brk(NULL)                               = 0x55a719717000
brk(0x55a719738000)                     = 0x55a719738000
read(0, 100
"100\n", 1024)                  = 4
nanosleep({tv_sec=0, tv_nsec=1000}, NULL) = 0
nanosleep({tv_sec=0, tv_nsec=1000}, NULL) = 0
lseek(0, -1, SEEK_CUR)                  = -1 ESPIPE (Illegal seek)
exit_group(0)                           = ?
+++ exited with 0 +++

Isn't this strange? why malloc didn't use brk or mmap for the allocation of memory (between the 2 calls for nanosleep()). What's the reason for this strange behaviour?

If I change my input to 200000 I see a call to mmap in between.


Solution

  • Isn't this strange?

    No.

    why malloc didn't use brk or mmap for the allocation of memory (between the 2 calls for nanosleep()).

    Scenario 1: You enabled optimisation, and the optimiser sees that omitting the call to malloc is not observable, and thus it was never called.

    Scernario 2: malloc was called, but it presumably didn't need to call brk nor mmap at that point. Both brk and mmap had been called earlier, possibly for purposes of malloc.