存储空间布局

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

一般分为以下几个部分:

(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

 

  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

时间: 2024-10-01 13:57:06

存储空间布局的相关文章

《APUE》读书笔记—第七章进程环境

本章主要介绍了Unix进程环境,包含main函数是如何被调用的,命令行参数如何传递,存储方式布局,分配存储空间,环境变量,进程终止方法,全局跳转longjmp和setjmp函数及进程的资源限制. main函数的原型为int main(int argc,char *argv[]);其中argc是命令行参数的数目,argv是指向参数的各个指针构成的数组.当内核执行C程序时,使用一个exec函数,在调用main函数前线调用一个特殊的启动例程,从内核获取命令行参数和环境变量. 进程终止分为正常终止和异常

浅谈Linux环境下并发编程中C语言fork()函数的使用_C 语言

由fork创建的新进程被称为子进程(child process).fork函数被调用一次,但返回两次.子进程的返回值是0,而父进程的返回值则是新进程的进程ID.将子进程ID返回给父进程的理由是:因为一个进程的子进程可以有多个,并且没有一个函数使一个进程可以获得其所有子进程的进程ID.fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getpid以获得其父进程的进程ID. 使fork失败的两个主要原因是:系统中已经有了太多的进程,或者该实际用户ID的进程总数超过

C语言的fork函数在Linux中的进程操作及相关面试题讲解_C 语言

fork的意义 下图为,C 程序的存储空间布局(典型) 1.一个现有进程可以调用 fork 函数创建一个新进程. 2.fork 函数被调用一次,但返回两次, 两次返回的唯一区别是子进程的返回值是 0, 而父进程的返回值是新子进程的 PID. 3.子进程和父进程继续执行 fork 调用之后的指令. 在上图的存储空间布局中,父子进程只共享正文段,其余的都各自有独立的副本 (通常使用 copy-on-write 的策略,速度比较快). fork 的两种用法 1.父子进程同时执行不同的代码段典型应用:W

Linux虚拟地址空间布局以及进程栈和线程栈总结【转】

转自:http://www.cnblogs.com/xzzzh/p/6596982.html 原文链接:http://blog.csdn.net/freeelinux/article/details/53782986[侵删] 本文转自多个博客,以及最后有我的总结.我没有单独从头到尾写一个总结的原因是别人已经写得很好了,我不花大量时间是无法达到这水平的.   一:Linux虚拟地址空间布局 (转自:Linux虚拟地址空间布局)    在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中.这个沙

win7系统下关闭闭英特尔快速存储技术的方法教程

  Intel快速存储技术是一种可以提高磁盘的读写性能和保护磁盘的技术.不过使用该存储服务会占用大量的系统资源,如果你不需要该功能河东软件园小编建议你将其关闭,那么在win7系统下如何关闭Intel快速存储技术呢?下面我们看下详细的操作方法吧! 第一步.Win7系统如果安装了Intel快速存储技术支持的话,在桌面的,右下角会显示下面所示的图标. 第二步.双击托盘里面的Intel快速存储技术图标的话,就会弹出来下图所示的窗口,这其实就是快速存储服务的控制面板. 第三步.直接单击管理选项,也可以单击

Win7提示“英特尔(R)快速存储技术未在运行”怎么办?

  故障现象: 英特尔(R)RST 服务是英特尔快速存储服务,即 intel rapidst,该程序为配备 SATA 磁盘的台式机.移动电脑和服务器平台系统提供更高的性能和可靠性.当使用一个或多个 SATA 磁盘时,可因性能提高及耗电降低而获益.使用多个磁盘时,可增强对磁盘故障时数据丢失的保护,安装 Intel 快速存储服务前需要于 BIOS 中开启 AHCI 模式.很多计算机用户在开机后会发现 Intel(R) Rapid 状态为英特尔(R)RST 服务未在运行,右键选择打开英特尔快速存储技术

Win7桌面右下角提示“英特尔(R)快速存储技术未在运行”怎么办?

  故障现象: 英特尔(R)RST 服务是英特尔快速存储服务,即 intel rapidst,该程序为配备 SATA 磁盘的台式机.移动电脑和服务器平台系统提供更高的性能和可靠性.当使用一个或多个 SATA 磁盘时,可因性能提高及耗电降低而获益.使用多个磁盘时,可增强对磁盘故障时数据丢失的保护,安装 Intel 快速存储服务前需要于 BIOS 中开启 AHCI 模式.很多计算机用户在开机后会发现 Intel(R) Rapid 状态为英特尔(R)RST 服务未在运行,右键选择打开英特尔快速存储技术

Win7提示“英特尔(R)快速存储技术未在运行”怎么办

    故障现象: 英特尔(R)RST 服务是英特尔快速存储服务,即 intel rapidst,该程序为配备 SATA 磁盘的台式机.移动电脑和服务器平台系统提供更高的性能和可靠性.当使用一个或多个 SATA 磁盘时,可因性能提高及耗电降低而获益.使用多个磁盘时,可增强对磁盘故障时数据丢失的保护,安装 Intel 快速存储服务前需要于 BIOS 中开启 AHCI 模式.很多计算机用户在开机后会发现 Intel(R) Rapid 状态为英特尔(R)RST 服务未在运行,右键选择打开英特尔快速存储

最小化数据传输——在客户端存储数据

客户端|数据 将程序输出为其他的语言是程序员喜爱的事情之一,在WEB上我们有 两个不同编程环境:客户端(浏览器)和服务器端,根据HTTP协议的定义, 我们可以在编写在客户端输出其他语言的服务端程序,我们选择了作为服 务端语言.javascript作为客户端输出.在本问中我们将向您演示这样用 该方案把数据存储在客户端,并且在诸如:聊天室.新闻系统或其他您想 实现的应用上达到服务端和客户端(浏览器)的最小的数据传输. 要求以下支持:     PHP4     JavaScript     Frame