c 代码:
// 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;
}
当编译以下代码时:
printf("%10p\n", sbrk(0));
我收到了一个警告提示:
格式化字符串‘%p’需要的参数类型是‘void *’,但是第二个参数的类型是‘int’
问题1:为什么会出现这个提示?
但是在我执行了 malloc(1024 * 1024)
之后,程序似乎没有改变 break。
以下是输出:
9b12000
9b12000
9b12000
问题2:当启动时,这个过程是否会在堆上分配内存以备将来使用?或者编译器改变了分配的时间点?如果没有,为什么?
[更新] 总结:brk() 或 mmap()
在查看 TLPI 和 man 页面(得到 TLPI 作者的帮助)后,现在我理解了 malloc()
如何决定使用 brk()
或 mmap()
,如下:
mallopt()
可以设置参数来控制 malloc()
的行为,其中有一个参数名为 M_MMAP_THRESHOLD
,一般而言:
- 如果请求的内存小于该值,则使用
brk()
; - 如果请求的内存大于或等于该值,则使用
mmap()
。
该参数的默认值为 128kb
(在我的系统上),但在我的测试程序中,我使用了 1Mb,因此选择了 mmap()
。当我将请求的内存更改为 32kb 时,我看到了将使用 brk()
。
该书在 TLPI 第 147 和 1035 页提到了这一点,但我没有仔细阅读那部分内容。
关于该参数的详细信息可在 mallopt()
的 man 页面中找到。
unistd.h
头文件。 - JS1unistd.h
中的sbrk()
原型。如果没有原型,编译器会假定未知函数返回int
。 - JS1-Wall
编译,并看到了警告warning: implicit declaration of function ‘sbrk’
,非常好的提示! - Eric