Does malloc() use brk() or mmap()?

16,256

Solution 1

If we change the program to see where the malloc'd memory is:

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

void program_break_test() {
  printf("%10p\n", sbrk(0));

  char *bl = malloc(1024 * 1024);
  printf("%10p\n", sbrk(0));
  printf("malloc'd at: %10p\n", bl);

  free(bl);
  printf("%10p\n", sbrk(0));

}

int main(int argc, char **argv) {
  program_break_test();
  return 0;
}

It's perhaps a bit clearer that sbrk wouldn't change. The memory given to us by malloc is being mapped into a wildly different location.

You could also use strace on Linux to see what system calls are made, and find out that malloc is using mmap to perform the allocation.

Solution 2

malloc is not limited to using sbrk to allocate memory. It might, for example, use mmap to map a large MAP_ANONYMOUS block of memory; normally mmap will assign a virtual address well away from the data segment.

There are other possibilities, too. In particular, malloc, being a core part of the standard library, is not itself limited to standard library functions; it can make use of operating-system-specific interfaces.

Solution 3

If you use malloc in your code, it will call brk() at the beginning, allocated 0x21000 bytes from the heap, that's the address you printed, so the Question 1: the following mallocs requirements can be meet from the pre-allocated space, so these mallocs actually didn't call brk, it is a optimization in malloc. If next time you want to malloc size beyond that boundary, a new brk will be called (if not large than the mmap threshold).

Share:
16,256
Eric
Author by

Eric

while(fail) { pivot(); trial(); } while(succeed) { repeat(); improve(); }

Updated on June 01, 2022

Comments

  • Eric
    Eric almost 2 years

    c code:

    // program break mechanism
    // TLPI exercise 7-1
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void program_break_test() {
        printf("%10p\n", sbrk(0));
    
        char *bl = malloc(1024 * 1024);
        printf("%x\n", sbrk(0));
    
        free(bl);
        printf("%x\n", sbrk(0));
    
    }
    
    int main(int argc, char **argv) {
        program_break_test();
        return 0;
    }
    

    When compiling following code:

     printf("%10p\n", sbrk(0));
    

    I get warning tip:

    format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int’

    Question 1: Why is that?


    And after I malloc(1024 * 1024), it seems the program break didn't change.

    Here is the output:

    9b12000
    9b12000
    9b12000
    

    Question 2: Does the process allocate memory on heap when start for future use? Or the compiler change the time point to allocate? Otherwise, why?


    [update] Summary: brk() or mmap()

    After reviewing TLPI and check man page (with help from author of TLPI), now I understand how malloc() decide to use brk() or mmap(), as following:

    mallopt() could set parameters to control behavior of malloc(), and there is a parameter named M_MMAP_THRESHOLD, in general:

    • If requested memory is less than it, brk() will be used;
    • If requested memory is larger than or equals to it, mmap() will be used;

    The default value of the parameter is 128kb (on my system), but in my testing program I used 1Mb, so mmap() was chosen, when I changed requested memory to 32kb, I saw brk() would be used.

    The book mentioned that in TLPI page 147 and 1035, but I didn't read carefully of that part.

    Detailed info of the parameter could be found in man page for mallopt().