c - 为什么调用 sbrk(0) 两次会给出不同的值?

标签 c memory sbrk brk

我正在尝试理解 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);
}

最佳答案

您的程序执行以下调用序列:

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

第一次调用 printf 会在内部调用 mallocstdout 分配缓冲区(stdout 是行缓冲的默认情况下,但缓冲区是在您第一次打印时根据需要创建的)。

这就是为什么第二次调用 sbrk 返回不同的值。

( This answer 不直接相关,但来自 valgrind 的错误消息暴露了隐藏在 printf 内的底层 malloc 调用的存在。)

您的第二个示例预先执行所有 sbrk 调用,因此其他函数在您背后调用 malloc 不会产生任何意外。

关于c - 为什么调用 sbrk(0) 两次会给出不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54463620/

相关文章:

c - C 中的文本文件到数组

c - 为什么我收到错误 undefined reference to `getche' ?

postgresql - 删除postgresql中的临时文件

memory - Quartus 初始化 RAM

c - 关于我对first fit malloc function的做法的意见和建议

c - 如何释放 sbrk() 获得的内存?

c - 设置结构指针的整数会导致段错误

有人可以解释这两个初始化程序之间的区别吗?

c++ - 使用 malloc 分配比现有内存更多的内存

c - TDM-GCC - 在 Kernighan & Ritchie 的存储分配器实现程序中未定义对 sbrk() 的引用