为什么第一个sbrk的返回值与后续调用不同?

时间:2019-01-27 22:42:04

标签: c memory sbrk brk

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

不确定第一个值为何与其他三个值不同吗?

1 个答案:

答案 0 :(得分:3)

执行// initialize SVG.js var draw = SVG('drawing') // Define the patterns. Multiple `svg()` calls don't clobber each other. draw.defs().svg("<pattern id='chevrons' patternUnits='userSpaceOnUse' width='60' height='30'><svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='60' height='30'><defs><rect id='r' width='30' height='15' fill='white' stroke-width='2.5' stroke='black'/><g id='p'><use xlink:href='#r'/><use y='15' xlink:href='#r'/><use y='30' xlink:href='#r'/><use y='45' xlink:href='#r'/></g></defs><use xlink:href='#p' transform='translate(0 -25) skewY(40)'/><use xlink:href='#p' transform='translate(30 0) skewY(-40)'/></svg></pattern>") draw.defs().svg("<pattern id='microbial' patternUnits='userSpaceOnUse' width='20' height=20><svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><rect width='40' height='40' fill='white'/><circle r='9.2' stroke-width='1' stroke='black' fill='none'/><circle cy='18.4' r='9.2' stroke-width='1px' stroke='black' fill='none'/><circle cx='18.4' cy='18.4' r='9.2' stroke-width='1' stroke='black' fill='none'/></svg></pattern") // Load the pattern by id var pattern = SVG.get('chevrons') // Apply it draw.circle(100).move(100, 50).stroke({width: 1, color: "black"}).fill(pattern) 时,它正在调用/使用printf,后者将自己对malloc进行调用以分配一些空间并将其添加到内存堆/池中。 / p>

第一个 必须分配一些空间,因此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;
}