一个具有多个源文件的程序经过编辑(editing)、编译(compiling)和连接(linking)后,产生一个文件,即可执行模块(executable module),以供运行。每个以磁盘文件形式存在的可执行模块一般包括两个分区:代码区和数据区,而当系统将可执行模块装载到内存中以便运行时,由系统将栈区和堆区加进程序的内存区中,因此,一个准备运行的程序在内存区中共有四个分区:代码区、数据区、栈区和堆区。
- 所有函数(包括主函数、非主函数、各类中的成员函数)的代码通常被存放在内存的代码区。
- 全局变量和所有静态(外部和内部)变量通常被存放在内存的数据区。
- 所有函数(包括主函数、非主函数、各类中的成员函数)中的局部变量(包括自动变量和寄存器变量)、函数参数、所用通用寄存器值、返主地址等通常在该函数被调用时,被存放在内存的栈区。
(通常情况下,只有当定义它的函数被调用时才存在的对象称为自动对象,自动对象在每次调用函数时创建和撤销。编译器把自动对象通常存放在内存的栈区,当函数结束的时候,会释放它的局部存储空间,自动对象和形参的值都不能再访问了。)栈是线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数,操作系统在切换线程的时候会自动切换栈,就是切换SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。
- 使用new,malloc所分配的空间被存放在内存的堆区。(什么是堆?)堆是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是用完了一定要记着还给操作系统,不然就会发生内存泄露。
各类变量所存放的内存存储分区:
寄存器变量被存放在CPU中的寄存器(register)内。
自动变量被存放在内存中的栈区(stack area)内。当控制流进入函数(包括主函数)体内时(即调用该函数时),该函数中的所有自动变量被逐个推入(push)栈内,而当函数运行结束,控制流退出该函数时,这些自动变量又按“先进后出”的顺序被弹出(pop)栈区。当另一个函数被调用时,该栈区又被用于存放另一个函数的自动变量。
全局变量(包括静态变量)被存于内存的数据区内,因此在该程序的所有源文件中始终都是可见的,也是存在的。
内部静态变量虽也被存于内存的数据区内,因而也是始终存在的,但只在调用函数时才可见。