为什么第一个 sbrk 的 return 值与后续调用不同?
Why is the return value of the first sbrk different than subsequent calls?
我想了解内存在 C 中的工作原理,所以现在正在试验 sbrk
函数。我知道sbrk(0)
应该return当前程序break,也就是数据段的结尾。
所以我尝试多次调用 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.
我不确定为什么第一个值与其他三个值不同,有什么想法吗?
当您执行 printf
时,它是 calling/using malloc
,它将自己调用 sbrk/brk
以分配一些 space 并添加它到内存 heap/pool.
第一个要分配一些space,所以sbrk
值就上去了。后续的可以重用 space,因此他们不会再做自己的 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
我想了解内存在 C 中的工作原理,所以现在正在试验 sbrk
函数。我知道sbrk(0)
应该return当前程序break,也就是数据段的结尾。
所以我尝试多次调用 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.
我不确定为什么第一个值与其他三个值不同,有什么想法吗?
当您执行 printf
时,它是 calling/using malloc
,它将自己调用 sbrk/brk
以分配一些 space 并添加它到内存 heap/pool.
第一个要分配一些space,所以sbrk
值就上去了。后续的可以重用 space,因此他们不会再做自己的 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