• 【C++上层应用】3. 动态内存


    • C++ 程序中的内存分为两个部分:
      • :在 函数内部 声明的所有变量都将占用栈内存
      • :这是程序中未使用的内存,在程序运行时可用于 动态分配内存

    【 1. new和delete运算符 】

    • 在 C++ 中,我们可以使用 new 运算符 为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址
    • 如果我们不再需要动态分配的内存空间,可以使用 delete 运算符 删除之前由 new 运算符分配的内存

    1.1 new 分配内存

    • new 运算符来为任意的数据类型动态分配内存的通用语法:
    new data-type;
    // 其中,data-type 可以是包括数组在内的任意内置的数据类型,
    // 也可以是包括类或结构在内的用户自定义的任何数据类型。
    
    • 1
    • 2
    • 3
    • 实例
      定义一个指向 double 类型的指针,然后请求内存,该内存在执行时被分配:
    double* pvalue  = NULL; // 初始化为 null 的指针
    pvalue  = new double;   // 为变量请求内存
    
    • 1
    • 2
    • 检查内存是否分配成功:如果自由存储区已被用完,可能无法成功分配内存。所以建议检查 new 运算符是否返回 NULL 指针,并采取以下适当的操作:
    double* pvalue  = NULL;
    if( !(pvalue  = new double ))
    {
       cout << "Error: out of memory." <<endl;
       exit(1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • malloc() 函数 在 C 语言中就出现了,在 C++ 中仍然存在,但建议尽量 不要使用 malloc() 函数 。new 与 malloc() 函数相比,其主要的优点是:new 不只是分配了内存,它还创建了对象。

    1.2 delete 释放内存

    • 在任何时候,当我们觉得某个已经动态分配内存的变量不再需要使用时,我们可以使用 delete 操作符释放它所占用的内存,释放内存的通用算法:
    delete pvalue;        // 释放 pvalue 所指向的内存
    
    • 1

    1.3 实例

    #include 
    using namespace std;
    
    int main ()
    {
       double* pvalue  = NULL; // 初始化为 null 的指针
       pvalue  = new double;   // 为变量请求内存
    
       *pvalue = 29494.99;     // 在分配的地址存储值
       cout << "Value of pvalue : " << *pvalue << endl;
    
       delete pvalue;         // 释放内存
    
       return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    【 2. 数组的动态内存分配 】

    2.1 一维数组

    • 通用形式:
    // 动态分配,数组长度为 m
    int *array=new int [m]//释放内存
    delete [] array;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 或者:
    // 动态分配,数组长度为 m
    char* pvalue  = NULL;   // 初始化为 null 的指针
    pvalue  = new char[20]; // 为变量请求内存
    
    // 释放内存
    delete [] pvalue;        // 删除 pvalue 所指向的数组
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.2 二维数组

    • 通用形式:
    int **array
    // 假定数组第一维长度为 m, 第二维长度为 n
    // 动态分配空间
    array = new int *[m];
    for( int i=0; i<m; i++ )
    {
        array[i] = new int [n]  ;
    }
    //释放
    for( int i=0; i<m; i++ )
    {
        delete [] arrary[i];
    }
    delete [] array;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 实例
    #include 
    using namespace std;
    
    int main()
    {
        int **p;   
        int i,j;   //p[4][8] 
        //开始分配4行8列的二维数据   
        p = new int *[4];
        for(i=0;i<4;i++){
            p[i]=new int [8];
        }
    
        for(i=0; i<4; i++){
            for(j=0; j<8; j++){
                p[i][j] = j*i;
            }
        }   
        //打印数据   
        for(i=0; i<4; i++){
            for(j=0; j<8; j++)     
            {   
                if(j==0) cout<<endl;   
                cout<<p[i][j]<<"\t";   
            }
        }   
        //开始释放申请的堆   
        for(i=0; i<4; i++){
            delete [] p[i];   
        }
        delete [] p;   
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    在这里插入图片描述

    2.3 三维数组

    • 通用形式:
    int ***array;
    // 假定数组第一维为 m, 第二维为 n, 第三维为h
    // 动态分配空间
    array = new int **[m];
    for( int i=0; i<m; i++ )
    {
        array[i] = new int *[n];
        for( int j=0; j<n; j++ )
        {
            array[i][j] = new int [h];
        }
    }
    //释放
    for( int i=0; i<m; i++ )
    {
        for( int j=0; j<n; j++ )
        {
            delete[] array[i][j];
        }
        delete[] array[i];
    }
    delete[] array;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 实例:
    #include 
    using namespace std;
    
    int main()
    {   
        int i,j,k;   // p[2][3][4]
    
        int ***p;
        p = new int **[2]; 
        for(i=0; i<2; i++) 
        { 
            p[i]=new int *[3]; 
            for(j=0; j<3; j++) 
                p[i][j]=new int[4]; 
        }
    
        //输出 p[i][j][k] 三维数据
        for(i=0; i<2; i++)   
        {
            for(j=0; j<3; j++)   
            { 
                for(k=0;k<4;k++)
                { 
                    p[i][j][k]=i+j+k;
                    cout<<p[i][j][k]<<" ";
                }
                cout<<endl;
            }
            cout<<endl;
        }
    
        // 释放内存
        for(i=0; i<2; i++) 
        {
            for(j=0; j<3; j++) 
            {   
                delete [] p[i][j];   
            }   
        }       
        for(i=0; i<2; i++)   
        {       
            delete [] p[i];   
        }   
        delete [] p;  
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    在这里插入图片描述

    【 3. 对象的动态内存分配 】

    • 对象的动态内存分配与简单的数据类型类似。
    • 实例:
      为一个包含四个 Box 对象的数组分配内存,构造函数将被调用 4 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(4次)。
    #include 
    using namespace std;
    
    class Box
    {
       public:
          Box() { 
             cout << "调用构造函数!" <<endl; 
          }
          ~Box() { 
             cout << "调用析构函数!" <<endl; 
          }
    };
    
    int main( )
    {
       Box* myBoxArray = new Box[4];
    
       delete [] myBoxArray; // 删除数组
       return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

  • 相关阅读:
    leetcode 50. Pow(x, n)
    洛谷P5309 Ynoi 2011 初始化 题解
    Vue3_2024_1天【Vue3创建和响应式,对比Vue2】
    【力扣题解】2139. 得到目标值的最少行动次数
    2D游戏案例:游戏场景搭建
    [JAVAee]SpringBoot-AOP
    浅析数据迁移工具Sqoop
    多级式多传感器信息融合中的状态估计(Matlab代码实现)
    在SpringBoot⼯程连接Redis
    spring boot自动装配及自动装配条件判断
  • 原文地址:https://blog.csdn.net/qq_44431690/article/details/134523638