一、什么是生命周期

生命周期,指的就是空间从诞生到消亡

  • 诞生:从内存中开辟出空间
  • 消亡:释放空间

只有在生命周期这段时间内,空间才是有效的,在生命周期外的时间,空间是无效的,不能访问


二、指令和常量的生命周期
指令在.text中,常量要么在.text中,要么在.rodata中,
指令和常量的生命周期为整个程序运行期间

疑问:为什么指令和常量的生命周期是整个程序运行期间?

就以指令为例来解释这个问题,假如在.text中,
某些指令所占空间的生命周期不是整个程序运行期间的话,这就麻烦了,
当程序运行到某个时间点需要调用某个函数时,结果函数指令所在空间因为生命周期到了而被释放了,
调用这个函数时就会调用失败,整个程序运行出错。


三、.data、.bss变量的生命周期

全局变量和静态局部变量的存储类为.data或者.bss
所以.data.bss变量指的就是全局变量和静态局部变量,
.data.bss变量的生命周期也为整个程序运行期间

也就是说程序一开始运行时变量空间就存在,直到到整个程序运行结束.data.bss被释放时,
.data.bss中的全局变量和静态局部变量才会被释放

为什么.data.bss变量的生命周期也为整个程序运行期间?

以全局变量为例,全局变量是所有函数共享操作的变量,如果运行到某个时刻被释放了,
也就是生命周期到了,这也扯淡了,这会导致某个正在使用该全局变量的函数出现严重错误

例子:

int i = 0; //i一直有效,直到程序运行结束

int fun()
{
    static int fnum = 0; //fnum一直有效,直到程序结束,每次调用fun函数时,累加的都是同一个fnum
    printf("%d\n", fnum++);
}

int main(void)
{
    for(i=0; i<5; i++)
    {
        fun();
    }
}

四、栈变量的生命周期

形参和自动局部变量的存储类为栈,所以栈变量指的就是形参和自动局部变量

在第一章就讲过,定义形参和自动局部变量的代码,编译后会变成代码块的压栈、弹栈指令

我们写一个伪代码

伪代码

int fun(int a)         编译后              fun
{                                          {
    int b;                                     push a //压栈,从栈中给a开辟空间 
    ...                                        push b //压栈
    ...

    if(a>100)                                   if
    {                                           {
        int c;                                      push c //压栈
        ...                                         ...
                                                    pop c  //弹栈
    }                                           }

                                                pop b  //弹栈,释从栈中开辟的空间b
                                                pop a  //弹栈,先压栈的后弹栈
}                                           }

栈变量的生命周期 =push 指令开辟空间 到 pop指令释放空间 期间

代码块开始运行时执行push,代码块运行结束时执行pop

因此栈变量的生命周期约等于代码块的生命周期

例子:

int fun(int a)    //a生命周期:代码块fun的生命周期
{
    int b;        //b生命周期:代码块fun的生命周期

    if(a > 100)
    {
        int c;             //c生命周期:代码块if的生命周期
        c = a + b;
    }

    {
        int d;              //d生命周期:代码块的生命周期
        d = 2*c;
    }
}

疑问:register变量的生命周期?

认为与栈变量相同。


五、堆变量的生命周期

malloc成功后,堆变量的生命周期开始,调用free将空间释放后,生命周期结束。

所以堆变量的生命周期 == mallocfree 之间的时间

疑问:如果忘了free怎么办呢?

程序运行结束时整个堆会释放,堆中忘了free的堆变量空间自然也会被释放,
但是一定要在程序运行时就free,不要等到程序运行结束再释放