我正在尝试了解sbrk()
函数。
据我所知:
sbrk(0)
返回中断的当前地址,并且不递增。
sbrk(size)
将中断的地址增加size
个字节,并返回中断的前一个地址。
所以我创建了一些东西来测试它:
#include <unistd.h>
#include <stdio.h>
int main(void)
{
printf("sbrk(0) = %p\n", sbrk(0)); // should return value x
printf("sbrk(0) = %p\n", sbrk(0)); // should return value x
printf("sbrk(5) = %p\n", sbrk(5)); // should return value x
printf("sbrk(0) = %p\n", sbrk(0)); // should return value x + 5
}
所以我期望看到这样的结果:
sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1677000 // x value
sbrk(5) = 0x1677000 // x value
sbrk(0) = 0x1677005 // x value + 5
但是我得到了这个:
sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1698000 // y value
sbrk(5) = 0x1698000 // y value
sbrk(0) = 0x1698005 // y value + 5
sbrk(0)
的前两个调用为什么不返回相同的值?
在这两个更改中断地址的呼叫之间会发生什么?
编辑: 将地址存储在变量中可以解决问题:
int main(void)
{
void *toto1 = sbrk(0);
void *toto2 = sbrk(0);
void *toto3 = sbrk(5);
void *toto4 = sbrk(0);
printf("sbrk(0) = %p\n", toto1);
printf("sbrk(0) = %p\n", toto2);
printf("sbrk(5) = %p\n", toto3);
printf("sbrk(0) = %p\n", toto4);
}
答案 0 :(得分:6)
您的程序执行以下调用序列:
sbrk()
printf()
sbrk()
printf()
...
对printf
的第一个调用在内部调用malloc
来为stdout
分配一个缓冲区(stdout
默认是行缓冲的,但是该缓冲区是按需创建的,第一个时间打印到它)。
这就是为什么第二次调用sbrk
返回不同的值的原因。
({This answer并没有直接关系,但是来自valgrind的错误消息暴露了隐藏在malloc
中的底层printf
调用的存在。)
您的第二个示例预先执行了所有sbrk
调用,因此,其他函数在您的背后调用malloc
并不令人惊讶。