C中的静态内存分配

时间:2015-07-31 10:04:18

标签: c static-memory-allocation

 #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;
 }

该程序的输出结果如下:

_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

任何人都可以解释以下内容吗?

  • 为什么地址具有不同的字节,例如。主要的,复发的static_varibale地址为6 * 4 = 24字节,堆为7 * 4 = 28字节,堆栈为12 * 4 = 48字节地址。
  • 虽然我为每个malloc分配100个字节,但malloc 1和malloc 2地址之间的差异是0x70 = 112字节
  • 为什么foo的地址和内容之间存在0x601050-0x601048 = 8的区别,尽管它们都是int而int只需要4个字节?

2 个答案:

答案 0 :(得分:3)

首先要明确的是,地址是进程内存空间的虚拟内存地址。也就是说,对于32位环境,进程内存空间的布局或多或少是这样的:

  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 +----------------------------------------+
  • 静态变量地址的大小不是很短,所有地址都是32位地址,只有printf()截断前导零(请参见上图,静态变量的地址较低)。 / p>

  • 除了分配的缓冲区本身之外,
  • malloc()通常会放置bookeeping数据。这是依赖于实现的。

  • &#34; int只占用4个字节&#34;,这取决于您的系统。编译器也可以为堆栈帧对齐添加填充。

答案 1 :(得分:2)

  • 程序的每个部分(代码,数据,堆栈......)都存在于不同的部分。这些部分由操作系统映射到内存区域,因此答案是您看到的差异取决于操作系统。在您的情况下,堆栈恰好映射到更高的区域,但所有地址仍然是64位(但地址空间可能更少,如48位)。
  • malloc()保证返回对齐的指针。在64位环境中,它通常位于16字节边界上,因此您分配的100个字节将被舍入&#39;到112(7 * 16)进行下一次分配。此外,malloc()需要使用其他数据跟踪分配,因此使用的空间将始终高于malloc的数量。
  • stufffoo之间的主要区别在于,其中一个已初始化而另一个未初始化,因此stuff将放置在.data部分,{ {1}}将放置在foo部分(零初始化部分)中。这意味着这两个变量不太可能彼此相邻。在你的情况下,他们很近,因为没有别的。