为什么两次调用sbrk(0)会给出不同的值? [英] Why does calling sbrk(0) twice give a different value?

查看:115
本文介绍了为什么两次调用sbrk(0)会给出不同的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图了解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是行缓冲的,但是该缓冲区是在您第一次打印到它时按需创建的.) /p>

这就是为什么第二次调用sbrk会返回不同值的原因.

(此答案没有直接关系,但是来自valgrind的错误消息暴露了底层malloc的存在隐藏在printf内部的呼叫.)

您的第二个示例在前面执行了所有sbrk调用,因此,在您后面执行其他调用malloc的功能不会感到惊讶.

I'm trying to understand the sbrk() function.

From what I know:
sbrk(0) returns the current address of the break and doesn't increment it.
sbrk(size) increments the address of the break by size bytes and returns the previous address of the break.

So I created something to test it:

#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
}

So I'm expecting to see a result looking like this:

sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1677000 // x value
sbrk(5) = 0x1677000 // x value
sbrk(0) = 0x1677005 // x value + 5

but instead I'm getting this:

sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1698000 // y value
sbrk(5) = 0x1698000 // y value
sbrk(0) = 0x1698005 // y value + 5

Why don't the first two calls of sbrk(0) return the same value? What happens between those two calls that changes the break address?

EDIT : Storing addresses in variables solves the problem:

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);
}

解决方案

Your program performs the following sequence of calls:

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

The first call to printf calls malloc internally to allocate a buffer for stdout (stdout is line buffered by default, but the buffer is created on demand the first time you print to it).

That's why the second call to sbrk returns a different value.

(This answer is not directly related, but the error messages from valgrind expose the existence of the underlying malloc call hidden inside printf.)

Your second example performs all sbrk calls up front, so there are no surprises from other functions calling malloc behind your back.

这篇关于为什么两次调用sbrk(0)会给出不同的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆