Bib*_*bas 11 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
}
Run Code Online (Sandbox Code Playgroud)
所以我期待看到如下结果:
sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1677000 // x value
sbrk(5) = 0x1677000 // x value
sbrk(0) = 0x1677005 // x value + 5
Run Code Online (Sandbox Code Playgroud)
但相反,我得到了这个:
sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1698000 // y value
sbrk(5) = 0x1698000 // y value
sbrk(0) = 0x1698005 // y value + 5
Run Code Online (Sandbox Code Playgroud)
为什么前两个调用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);
}
Run Code Online (Sandbox Code Playgroud)
您的程序执行以下调用序列:
sbrk()
printf()
sbrk()
printf()
...
Run Code Online (Sandbox Code Playgroud)
第一次printf调用malloc内部调用以分配缓冲区stdout(stdout默认情况下是行缓冲,但是第一次打印时会根据需要创建缓冲区).
这就是第二次调用sbrk返回不同值的原因.
(这个答案没有直接关系,但来自valgrind的错误消息暴露了malloc隐藏在里面的底层调用的存在printf.)
您的第二个示例预先执行所有sbrk呼叫,因此其他功能malloc在您背后呼叫时不会出现意外情况.