程序在运行过程中,数据在存储器中是怎样分布的又是怎样变化的?堆栈在函数调用的过程中是怎样活动的?以下几点可能帮助读者解读此问题:
- 内存分布:当程序运行到main函数时,程序员定义的全局变量或者静态变量已经在内存中分配好了,当然是链接器加入的代码发挥的作用,同时还会初始化堆栈区域。具体存储器空间分布为:代码区→只读数据区→初始化数据区→未初始化数据区→堆区→······←栈区→命令行参数区,环境变量。不同的计算机架构和工具链,存储器分布可能有略微差别;
- 代码区:程序存储空间;
- 只读数据区:字符串常量,const修饰的全局变量和静态变量;
- 初始化数据区:初始化不为0的全局变量,初始化不为0的静态变量;
- 未初始化数据区:初始化为0的全局变量和静态变量,未初始化的全局变量和静态变量;
- 堆区:用于为程序员动态申请的变量分配空间;
- 栈区:用于为函数局部变量、参数、返回值自动分配空间,函数结束后自动释放空间。
- 命令行参数、环境变量区:操作系统中使用。
强调两点:
- 程序在进入main函数之前,已经完成数据在内存中的分配、初始化,包括数据区,堆栈区等。关于这部分代码对于开发者不可见,属于C标准运行时的一部分。
- 函数在调用和被调用过程中,都伴随着入栈和出栈的活动,因此栈发挥着重要作用。函数的局部变量、参数、返回值都存在栈区中。函数结束后,栈区空间自动释放,栈区担任着一个临时存储的角色,是计算机利用内存空间的一种机制。