Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
453 views
in Technique[技术] by (71.8m points)

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

c code:

// program break mechanism
// TLPI exercise 7-1

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

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

    char *bl = malloc(1024 * 1024);
    printf("%x
", sbrk(0));

    free(bl);
    printf("%x
", sbrk(0));

}

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

When compiling following code:

 printf("%10p
", 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().

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
", sbrk(0));

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

  free(bl);
  printf("%10p
", 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...