2

我试图了解内存在 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.

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

4

1 回答 1

3

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

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

如果您使用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  ................

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

#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
于 2019-01-27T22:53:02.030 回答