首页 /  技术专区  /  C 宽屏模式 >

指令、常量、变量的生命周期

1、 指令、常量、变量的生命周期

1.1 什么是生命周期

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

        诞生:从内存中开辟出空间。

        消亡:释放空间

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


1.2 指令和常量的生命周期

指令在.text中,常量要么在.text中,要么在.rodata中。

指令和常量的生命周期为整个程序运行期间,

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

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


1.3 .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();
    }
}

1.4 栈变量的生命周期

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

定义形参和自动局部变量的代码,编译后会变成代码块的压栈、弹栈指令。

我们写一个伪代码

int fun(int a)                      
{                                          
    int b;                                   
    ...                                         
    if(a>100)                                  
    {                                          
        int c;                                    
        ...                                       
    }
}																	

编译后伪代码

fun
{
    push a //压栈,从栈中给a开辟空间 
    push b //压栈
    ...
    if
    {
        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变量的生命周期?

认为与栈变量相同。


13.5 堆变量的生命周期

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

所以堆变量的生命周期 == malloc 到 free之间的时间。

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

程序运行结束时整个堆会释放,堆中忘了free的堆变量空间自然也会被释放,但是一定要在程序运行时就free,不要等到程序运行结束再释放,至于为什么要这样,在第1章有详细解释。


头像
0/200
图片验证码