I am trying to understand how memory works in C, so am experimenting with the sbrk
function now. I know that sbrk(0)
should return the current program break, that is the end of the data segment.
So I tried to call sbrk(0)
multiple times and for some reason I get the first value different than the other values. For example, this program
#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);
}
Give me the following output:
The current program break is: 0x18b0000.
The current program break is: 0x18d1000.
The current program break is: 0x18d1000.
The current program break is: 0x18d1000.
Am not sure why the 1st value is different than the other three values, any ideas?
When you do printf
, it is calling/using malloc
, which will do its own calls to sbrk/brk
to allocate some space and add it to the memory heap/pool.
The first one has to allocate some space, so the sbrk
value goes up. The subsequent ones can reuse that space, so they don't do their own sbrk
again. But, they now have the sbrk
value that has been perturbed by the first printf
call.
If you use write
and save the output to a file and examine it with a hex editor, you don't have the same problem. All values are the same:
#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;
}
Here is the hex output:
00000000: 00908401 00000000 00908401 00000000 ................
00000010: 00908401 00000000 00908401 00000000 ................
Another [simpler] way to see this is to do all sbrk
calls without the intervening 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;
}
The output of this is:
pb=0xc42000 sbrk=0xc42000
pb=0xc42000 sbrk=0xc63000
pb=0xc42000 sbrk=0xc63000
pb=0xc42000 sbrk=0xc63000