数据内存管理

根据用于分配内存的方法,C++提供了3种管理数据内存的方式:自动存储、静态存储和动态存储(也称自由存储空间或堆)。在存在时间的长短方面,以这3种方式分配的数据对象各不相同。

1、自动存储

在函数内部定义的常规变量使用自动存储空间,被称为自动变量,这意味着它们在所属的函数被调用时自动产生,在该函数结束时消亡。
实际上,自动变量是一个局部变量,其作用域为包含它的代码块。代码块是被包含在花括号中的一段代码。到目前为止,我们使用的所有代码块都是整个函数如for循环函数、if条件判断函数(特别注意:if( ; ; ){…},容易忽略)。函数内也可以有代码块,如果在其中的某个代码块定义一个变量,则该变量仅在程序执行该代码块中的代码时存在。
自动变量通常存储在栈中。这意味着执行代码块时,其中的变量将依次加入到栈中,而在离开代码块时,将按相反的顺序释放这些变量,这被称为后进先出。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

2、静态存储

静态存储是整个程序执行期间都存在的存储方式。使变量称为静态的方式有两种:一种是在函数外面定义它;另一种是在声明变量时使用关键字static。
自动存储和静态存储的关键在于:这些方法严格限制了变量的寿命。

3、动态存储

new和delete运算符提供了一种比自动变量和静态变量更灵活的方法。它们管理一个内存池,这在C++中被称自由存储空间或堆。该内存池同用于静态变量和自动变量的内存是分开的。
实例说明:
例1:

#include <stdio.h>
void main()
{
    int j = 1;
    for( int i=0, j=2; i < 3; i++)
    {
        for( int i=0; i < 3; i++)
        {
            int j = 4;  
            printf("%d	",j);
        }
        j++;
        printf("%d	",j);
        printf("%d	",i);
    }
    printf("%d
",j);
    while(1);
}

该程序在VS2010下的运行结果如下图所示:
这里写图片描述

注:为何这里要强调是在VS2010下的运行结果,那是因为在不同的软件下运行结果可能不同,这与其编译器种类有关。若在VC6.0下编译,则结果就不同。
说明:
1.外部for循环中的 i, j 与内部for循环中的 i, j是不一样的,它们占有不同的内存,而且都是在for函数内部定义的常规变量,故都为自动变量。特别要注意的是,i和j即使同为一个for循环下定义的自动变量,但它们的生命周期并不相同,有细微的差别:for下的小括号()中定义的自动变量,它是在整个for函数执行完之后才释放内存,而for下的大括号{ }中定义的自动变量,是在每次for循环后就释放内存。对比两个for循环函数中的 i、j 变量的变化可得此结论(在VS2010下逐步运行该程序,观察局部变量的变化)。这也是在for循环中(指大括号{ }中)重复定义变量,编译器不报错的原因所在。

2.同样,main()函数中的 j也是自动变量,与for函数中定义的 j不同,它们占有不同的内存。

例2:

#include <stdio.h>
void main()
{
    int j=1;
    for( int i=0; i < 2; i++)
    {
        if( i % 2 == 0 ){
            int j=2;
            printf("%d	",j);
        }           
        else{
            int j=3;
            printf("%d	",j);
        }           
        printf("%d	",j);
    }
    printf("%d	",j);
    while(1);
}

该程序在VS2010下的运行结果如下图所示:
这里写图片描述

说明:仔细分析可知,if函数中的变量j为局部变量,只在if函数内有效,当在if函数外时其内存被释放。与例1中的for函数同理。这里,特别容易忽略if是一个函数,通常我们只认为它仅是一条语句,其实不然,注意其内部定义的变量为自动变量。

参考资料:《 C++ Primer Plus (第6版)中文版 》P117-118

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/gongchuangsu/p/4850216.html