C语言 为什么调用 sbrk(0) 两次会给出不同的值



>我试图理解sbrk()函数。

据我所知:
sbrk(0) 返回中断的当前地址,并且不会递增它。
sbrk(size)将中断的地址递增 size 个字节,并返回中断的上一个地址。

所以我创建了一些东西来测试它:

#include <unistd.h>
#include <stdio.h>
int main(void)
{
    printf("sbrk(0) = %pn", sbrk(0)); // should return value x
    printf("sbrk(0) = %pn", sbrk(0)); // should return value x
    printf("sbrk(5) = %pn", sbrk(5)); // should return value x
    printf("sbrk(0) = %pn", 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) = %pn", toto1);
    printf("sbrk(0) = %pn", toto2);
    printf("sbrk(5) = %pn", toto3);
    printf("sbrk(0) = %pn", toto4);
}

程序执行以下调用序列:

sbrk()
printf()
sbrk()
printf()
...

printf的第一次调用malloc内部为stdout分配缓冲区(默认情况下,stdout是行缓冲的,但缓冲区是在第一次打印到缓冲区时按需创建的)。

这就是对 sbrk 的第二次调用返回不同值的原因。

(这个答案没有直接关系,但来自 valgrind 的错误消息暴露了隐藏在 printf 中的底层malloc调用的存在。

您的第二个示例预先执行所有sbrk调用,因此在您背后调用malloc的其他函数不会感到惊讶。

相关内容

  • 没有找到相关文章

最新更新