Reputation: 8152
#include <stdio.h>
#include <stdlib.h>
int foo; /* a staticly allocated variable */
int recur(int i) { /* a recursive function */
int j = i; /* a stack allocated variable within a recursive function */
printf("recur call (i)%d: stack@ %lx\n", i, (long unsigned int) &j); /* fix this so it print
s the address of j */
if (i > 0) {
return recur(i-1);
}
return 0;
}
int stuff = 7; /* a statically allocarted, pre-initialized variable */
int main (int argc, char *argv[]) {
int i; /* a stack allocated variable */
char *buf1 = malloc(100); /* dynamically allocate some stuff */
char *buf2 = malloc(100); /* and some more stuff */
char *buf3 = malloc(100); /* and some more stuff */
printf("_main @ %lx\n", (long unsigned int) &main); /* fix to print address of main */
printf("_recur @ %lx\n", (long unsigned int) &recur); /* fix to print address of recur */
printf("main call (i):stack@ %lx\n", (long unsigned int) &i); /* fix to get address of the s
tack variable */
printf("_static foo: %lx\n", (long unsigned int) &foo); /* fix to get address of the static v
ariable */
printf("_static stuff: %lx\n", (long unsigned int) &stuff); /* fix to get address of a stati
c variable */
printf("Heap: malloc 1: %lx\n", (long unsigned int) buf1);
printf("Heap: malloc 2: %lx\n", (long unsigned int) buf2);
printf("Heap: malloc 3: %lx\n", (long unsigned int) buf3);
recur(3);
return 0;
}
The output of this program comes out to be:
_main @ 4005c2
_recur @ 40057d
main call (i):stack@ 7fff26397694
_static foo: 601050
_static stuff: 601048
Heap: malloc 1: 1862010
Heap: malloc 2: 1862080
Heap: malloc 3: 18620f0
recur call (i)3: stack@ 7fff2639766c
recur call (i)2: stack@ 7fff2639763c
recur call (i)1: stack@ 7fff2639760c
recur call (i)0: stack@ 7fff263975dc
Can anyone please explain followings?
Upvotes: 0
Views: 2010
Reputation: 14174
First let be clear that addresses are virtual memory addresses of your process memory space. That said, the layout of a process memory space is more or less like this for a 32bit environment:
0 +----------------------------------------+
| .text (code) |
+----------------------------------------+
| .data (initialized static variables) |
+----------------------------------------+
| .bss (uninitialized static variables) |
+----------------------------------------+ <- Heap start, grows upwards
| heap |
+----------------------------------------+
| stack |
3GB +----------------------------------------+ <- Stack start, grows downwards
| kernel code |
4GB +----------------------------------------+
Static variables addresses are not of shorter sizes, all addresses are 32bit addresses, it's only printf()
truncating leading zeroes (Look at the diagram above, static variables have low addresses).
malloc()
usually places bookeeping data in addition to the allocated buffer itself. This is implementation dependent though.
"int
takes just 4 bytes", that depends on your system. Also the compiler could have added padding for stack frame alignment.
Upvotes: 3
Reputation: 6145
malloc()
is guaranteed to return an aligned pointer. In 64-bit environment, it usually is on a 16 bytes boundary, thus the 100 bytes you allocate will be 'rounded' to 112 (7*16) for the next allocation. Also, malloc()
need to keep track of allocation with additional data, so the used space will always be higher than the malloc'ed amount.stuff
and foo
is that one is initialized and the other one is not, thus stuff
will be placed in the .data
section, and foo
will be placed in the .bss
section (zero initialized section). This means that the two variable are unlikely to be next to each other. In your case they are near because there is nothing else.Upvotes: 2