变量的生存期和存储分配

1.变量的生存期 

 变量是内存空间的一种抽象,程序中定义的每个变量在运行时都有与之对应的内存空间。

  C++把变量占有的内存空间的时间段称为生存期,分为三类:静态生存期、动态生存期、自动生存期

  • 全局变量具有静态生存期;
  • 局部变量和函数的参数一般具有自动生存期;
  • 对于具有动态生存期的变量,其内存空间一般用new操作分配,用delete操作收回,这样的变量称为动态变量,动态变量具有动态生存期。

  定义局部变量时,可以加上存储类型修饰符:auto、static或register来显式地指出他们的生存周期。

  • 局部变量的默认存储类型为auto;
  • 定义static存储类型的局部变量具有静态生存期;
  • 定义register存储类的局部变量也具有自动生存期,与auto存储类的局部变量的区别在于register是建议编译程序将相应的局部变量的空间分配在CPU的存储器中,目的是提高对局部变量的访问效率,当然,register类型的局部变量的存储空间也可以在CPU的寄存器中,或者内存中。

  在C++程序中,定义的一个变量如果没有初始化,对于具有静态生存期的变量(全局变量、static存储类的局部变量),程序会隐式地自动把他们按位模式初始化为0;对于其他变量,编译程序不会初始化,初始值为内存空间已有的值,具有不确定性。

2.作用

  • 自动的局部变量起到节省内存空间的作用,当包含auto存储类的局部变量的函数调用结束后,其中的自动局部变量的内存就被收回了。
  • static存储类的局部变量的作用是,能在函数调用时获得上一次调用结束时该局部变量的值,即能在函数多次调用之间得以保留。

特别注意的是,static存储类的局部变量如果在定义中初始化,则该初始化只在函数第一次调用时进行,后面的调用中不再初始化,它的值为上一次调用结束时的值,受函数封装的保护。

3.存储的分配  

  当一个程序运行时,操作系统会为其分配一个内存空间,包括四个部分:静态数据区(static data)、代码区(code)、栈区(stack)和堆区(heap,或称自由存储区,free store),如下图所示(不同操作系统的顺序会不同)。

  在程序的内存空间中:

  • 静态数据区用于全局变量、static存储类的局部变量以及变量的内存分配;
  • 代码区用于存放程序的指令,对于C++,代码区存放的是所有函数的代码;
  • 栈区用于auto存储类的局部变量、函数的参数,及函数调用时的有关信息(如函数的返回地址等)的内存分配;
  • 堆区用于动态变量的内存分配

   静态数据区和代码区的大小是固定的,而栈区和堆区的大小将会随着程序的运行不断变化,不过,操作系统对于程序的栈区和堆区的最大值有一定的限制。

4.基于栈的函数调用的实现

  函数调用是通过栈来实现的,栈是一种元素个数可变的线性数据结构。其元素的增加和减少只能在某一端进行。

  1. 在C++函数调用时,调用者在栈中为形参函数返回地址分配空间,并将函数中实参的值和调用后的返回地址放入所分配的栈空间中;
  2. 函数调用中,被调用的函数在栈中为自动存储类的局部变量分配空间,并从栈中(通过形参)获得调用者提供的数据(实参的值);
  3. 函数调用后,被调用者释放局部变量的栈空间,并根据栈空间的返回地址返回到调用点(存储返回地址的栈空间将被释放);
  4. 调用者释放形参占用的的栈空间,然后继续执行调用之后的操作。

堆栈顺序:形参->函数返回地址->函数内的auto局部变量

   

原文地址:https://www.cnblogs.com/guojun-junguo/p/9998236.html