存储空间布局

了解存储空间布局意义很大,这对加深理解局部函数返回值,堆和栈很有帮助

一般分为以下几个部分:

(1) 栈
由编译器自动分配释放管理。局部变量及每次函数调用时返回地址、以及调用者的环境信息(例如某些机器寄存器)都存放在栈中。新被调用的函数在栈上为其自动和临时变量分配存储空间。通过以这种方式使用栈,C函数可以递归调用。递归函数每次调用自身时,就使用一个新的栈帧,因此一个函数调用实例中的变量集不会影响另一个函数调用实例中的变量。
a.局部变量
b.函数调用时返回地址
c.调用者的环境信息(例如某些机器寄存器)

(2) 堆
需要由程序员分配释放管理,若程序员不释放,程序结束时可能由OS回收。通常在堆中进行动态存储分配。
如程序中的malloc, calloc, realloc等函数都从这里面分配。堆是从下向上分配的。

(3) 非初始化数据段
通常将此段称为bss段,这一名称来源于早期汇编程序的一个操作符,意思是“block started by symbol(由符号开始的块)”,未初始化的全局变量和静态变量存放在这里。在程序开始执行之前,内核将此段初始化为0。函数外的说明:long sum[1000] ; 使此变量存放在非初始化数据段中。
a.未初始化的全局变量
b.未初始化的静态变量

(4) 初始化的数据
通常将此段称为数据段,它包含了程序中需赋初值的变量。初始化的全局变量和静态变量存放在这里。例如,C程序中任何函数之外的说明:int maxcount = 99; 使此变量以初值存放在初始化数据段中。
a.初始化的全局变量
b.初始化的静态变量

(5) 正文段
CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是经常环境指针环境表环境字符串执行的程序(如文本编辑程序、C编译程序、s h e l l等)在存储器中也只需有一个副本,另外,正文段常常是只读的,以防止程序由于意外事故而修改其自身的指令。
结构如下图所示


给出一个前辈关于这个代码描述:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int a = 0; //全局初始化区   
  2. char *p1; //全局未初始化区   
  3. main()   
  4. {   
  5.     int b; //栈   
  6.     char s[] = "abc"//栈   
  7.     char *p2; //栈   
  8.     char *p3 = "123456"//123456\0在常量区,p3在栈上。   
  9.     static int c =0; //全局(静态)初始化区   
  10.     p1 = (char *)malloc(10); //堆   
  11.     p2 = (char *)malloc(20);  //堆   
  12. }  

关于堆和栈区别的比喻

堆和栈的区别也可以引用一位前辈的比喻来理解: 

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大


转载:http://blog.csdn.net/xsf50717/article/details/39996231