【问题标题】:Why is the return value of the first sbrk different than subsequent calls? [duplicate]为什么第一个 sbrk 的返回值与后续调用不同? [复制]
【发布时间】:2019-01-27 22:42:03
【问题描述】:

我正在尝试了解内存在 C 中是如何工作的,所以我现在正在尝试 sbrk 函数。我知道sbrk(0)应该返回当前的程序中断,也就是数据段的结束。

所以我尝试多次调用sbrk(0),但由于某种原因,我得到的第一个值与其他值不同。比如这个程序

#include <stdio.h>
#include <unistd.h>

int main()
{
        void * currpb = sbrk(0);
        printf("The current program break is: %p.\n", currpb);

        void * newpb = sbrk(0);
        printf("The current program break is: %p.\n", newpb);

        void *new2pb = sbrk(0);
        printf("The current program break is: %p.\n", new2pb);

        void *new3pb = sbrk(0);
        printf("The current program break is: %p.\n", new3pb);
}

给我以下输出:

The current program break is: 0x18b0000.
The current program break is: 0x18d1000.
The current program break is: 0x18d1000.
The current program break is: 0x18d1000.

不确定为什么第一个值与其他三个值不同,有什么想法吗?

【问题讨论】:

  • (您的 printfs 错误;new2pb 不是 int。)Fixed demo
  • 嗯,那是什么?
  • 错误...void *?这是你的变量,你应该知道,你做到了! :-) 您需要%p 格式说明符,或者将指针转换为适当的整数类型(例如uintptr_t)并使用适当的说明符。但是%p 应该可以很好地展示这种情况。 (顺便说一句,好问题。)
  • 是的,有道理,好的,我使用了 %p,它返回了地址,我将编辑我的问题
  • 对于这样一个特定问题的欺骗从未如此准确。确实,当我看到这个问题时,我以为是那个老问题因为某种原因被撞了。

标签: c memory sbrk brk


【解决方案1】:

当您执行printf 时,它正在调用/使用malloc,它将自己调用sbrk/brk 以分配一些空间并将其添加到内存堆/池中。

第一个必须分配一些空间,所以sbrk 的值会上升。后续的可以重用那个空间,所以他们不会再做自己的sbrk。但是,他们现在拥有被第一个 printf 调用扰乱的 sbrk 值。

如果您使用write 并将输出保存到文件并使用十六进制编辑器对其进行检查,则不会遇到同样的问题。所有值都相同:

#include <stdio.h>
#include <unistd.h>

int
main()
{
    void *pb;

    pb = sbrk(0);
    write(1,&pb,sizeof(pb));

    pb = sbrk(0);
    write(1,&pb,sizeof(pb));

    pb = sbrk(0);
    write(1,&pb,sizeof(pb));

    pb = sbrk(0);
    write(1,&pb,sizeof(pb));

    return 0;
}

这是十六进制输出:

00000000: 00908401 00000000 00908401 00000000  ................
00000010: 00908401 00000000 00908401 00000000  ................

另一种 [更简单] 的查看方式是在没有干预 printf 的情况下进行所有 sbrk 调用:

#include <stdio.h>
#include <unistd.h>

int
main()
{
    void *pb[4];

    for (int idx = 0;  idx < 4;  ++idx)
        pb[idx] = sbrk(0);

    for (int idx = 0;  idx < 4;  ++idx)
        printf("pb=%p sbrk=%p\n",pb[idx],sbrk(0));

    return 0;
}

这个的输出是:

pb=0xc42000 sbrk=0xc42000
pb=0xc42000 sbrk=0xc63000
pb=0xc42000 sbrk=0xc63000
pb=0xc42000 sbrk=0xc63000

【讨论】:

    猜你喜欢
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    相关资源
    最近更新 更多