Почему возвращаемое значение первого sbrk отличается от последующих вызовов?
Я пытаюсь понять, как работает память в 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-е значение отличается от трех других, есть идеи?
1 ответ
Когда вы делаете 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