C与C++存储空间布局

  每个程序一启动都有一个大小为4GB的内存,这个内存叫虚拟内存,是概念上的,真正能用到的,只是很小一部分,一般也就是在几百K到几百M。我们PC中内存,我们称之为物理内存,也就是256M,512M等,虚拟内存和物理内存的如何转换是由操作系统完成的,我们不需要管它。我们只需要管好我们自己程序的那4GB内存就可以了。
  要管理4GB的虚拟内存,就必须给每个字节分配一个号码,以便程序与访问到其中任何一个字节。这个号码是从0开始顺序递增的,针对于这个号码我们就称之为地址,从0x00000000-0xFFFFFFFF,这样,我们理论上就可以访问其中内存中任何一个字节了。但有一点请注意,系统并不让我们全部都可以用。其中后面2GB的内容是留给系统用的,用户是不可以访问的,而且在前面的2GB也有部分区段不能访问,比如0x00000000就不能访问。具体是哪些区段,不必关心。
  注意:类似于0x12345678或12345678H是10进制数305419896的16进制表示法,他们是一回事,显示16进制是为了方便显示及计算机计算。
  程序都是用来做一些具体的事情,不管做什么事,结构都是很相似。程序启动,就有4GB的虚拟内存,通过CPU的计算,改变内存的内容,最后再复制内存的内容输出,输出的目的地可以是:屏幕、文件、磁盘等外存、端口、网络等。如何输出呢,最后全部都是调用系统的API,由操作系统完成。
 

各部分说明如下:

(1)代码区(text segment):又称只读区。通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,比如字符串常量等。

(2)全局初始化数据区/静态数据区(Data Segment)用来存放程序已经初始化的全局变量,已经初始化的静态变量。位置位于可执行代码段后面,可以是不相连的。在程序运行之初就为数据段申请了空间,程序退出的时候释放空间,其生命周期是整个程序的运行时期。

(3)未初始化数据区(BSS):用来存放程序中未初始化的全局变量和静态变量,位置在数据段之后,可以不相连。其生命周期和数据段一样。(2)和(3)统称为静态存储区。

(4)栈区(Stack)又称堆栈,存放程序临时创建的局部变量,如函数的参数值、返回值、局部变量等。也就是我们函数括弧{}中定义的变量(但不包括static声明的静态变量,static意味着在数据段中存放的变量)。除此之外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且等到调用结束后,函数的返回值也会被存放回栈中。编译器自动分配释放,是向下有限扩展的。

(5)堆区(Heap)位于栈区的下面,是向上有限扩展的。用于存放进程运行中动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存的时候,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存的时候,被释放的内存从堆中被剔除(堆被缩减)。一般由程序员进行分配和释放,若不释放,在程序结束的时候,由OS负责回收。

const修饰的全局变量保存在代码区中,const修饰的局部变量保存在栈段中。

原文地址:https://www.cnblogs.com/fuleying/p/4456329.html