• 猿创征文 |【C++】动态内存的分配与回收


    一、回顾C中动态分配内存和回收的方式

    C中动态分配内存的方式
    1.malloc
    2. calloc
    3. realloc
    回收方式
    free

    代码如下:

    #include 
    #include 
    
    int main()
    {
        int *p1=(int *)malloc(sizeof(int));
        printf("%d\n",*p1);//没有初始化
        int *p2=(int *)calloc(1,sizeof (int));
        printf("%d\n",*p2);//有初始化
        int *p3=(int *)realloc(p2,sizeof(int)*10);
        printf("%d\n",*p3);//有初始化
        free(p1);
        //free(p2);
        //同一块堆区空间被多次释放会造成doublefree的现象,程序就会异常中止。
        free(p3);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    结果展示:
    在这里插入图片描述
    总结:

    1. malloc在堆上开辟空间并没有进行初始化。
    2. calloc在堆上开辟空间是有初始化。
    3. relloc在堆上开辟空间都是有初始化。
    4. 同一块堆区空间被多次释放会造成double free的现象,程序就会异常中止。

    二、C++中动态分配内存和回收的方式

    C++提供了新的关键字new来动态分配空间。
    同时为了回收空间,又提供关键字delete来释放空间。
    在C++中支持malloc/free,但是我们一般都使用 new/delete

    2.1 分配

    2.1.1 单个空间的分配

    格式: 数据类型 *指针名 = new 数据类型;
    如: int *p = new int;
    在堆区分配 1 个 int 大小的空间。

    2.1.2连续空间的分配

    格式: 数据类型 *指针名 = new 数据类型[个数];
    如: int *p = new int[5];
    在堆区分配 5 个 int 大小的空间,连续的。

    2.2 回收

    2.2.1 单个空间的回收

    delete 指针名;

    2.2.2 连续的空间的回收

    delete []指针名;
    []里面不用写长度,但是[]必须写,表示释放指针指向的连续空间。

    2.3 举例说明

    2.3.1 单个空间的举例

    代码如下:

    #include 
    using namespace std;
    
    int main()
    {
        int *pa=new int;
        *pa=100;
        cout << *pa << endl;
    	不初始化
        int *pb=new int;
        cout << *pb << endl;
    	//用0初始化
        int *pc = new int();
        cout<< *pc <<endl;
        delete pc;
    
        int *pd=new int(521);
        cout << *pd << endl;
    
        delete pa;
        delete pb;
        delete pc;
        delete pd;
        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

    结果展示:
    在这里插入图片描述

    总结:

    1. new分配的空间如果没有初始化,是随机值。
    2. 当在类型后加上()时,new分配的空间如果没有初始化,会自动用 0 进行初始化。
    3. 我们使用new时,一般都是直接初始化的操作,可以使用括号的方式直接初始化,new后面的内置类型后加个括号表示编译器在括号取值初始化内置类型所开辟的内存中的值。
    4. delete pa;使用delete释放已经开辟的空间。

    2.3.2 连续空间的举例

    代码如下:

    #include 
    using namespace std;
    
    int main()
    {
        int *pa=new int[10];
        int i=0;
        for(i=0;i<10;i++)
        {
            cout << pa[i] << ",";
        }
        cout << endl;
        cout << "-----------------------------" << endl;
        for(i=0;i<10;i++)
        {
            *(pa+i)=i;
        }
        for(i=0;i<10;i++)
        {
            cout << pa[i] << ",";
        }
        cout << endl;
        cout << "-----------------------------" << endl;
        int *pb=new int[10]{1,2,3};
        for(i=0;i<10;i++)
        {
            cout << pb[i] << ",";
        }
        delete []pa;
        delete []pb;
        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

    结果展示:
    在这里插入图片描述

    总结:

    1. int *pa=new int[10];此种连续开辟空间,是没有初始化的。内存中的值有很多是随机值的。
    2. 可以采用循环,或者采用int *pb=new int[10]{1,2,3};这种方式进行初始化。这是C++11的新语法。
    3. 如果是连续空间的开辟,一定要要使用delete[]的方式来释放。

    三、自定义类类型中的new/delete

    针对于内置类型而言,new大体相当mallocdelete大体相当于free

    但是如果自定义类类型
    new代表两种含义:开辟空间,调用类中的构造函数进行初始化
    delete也代表两含义:即调用类中的析构函数,然后再释放空间

    关于构造与析构在之后的文章会详细讲解,感兴趣可以关注一下!

    代码如下:

    #include 
    using namespace std;
    struct Stu
    {
        Stu()
        {
            cout << "Stu的构造" << endl;
        }
        ~Stu()
        {
            cout << "Stu的析构" << endl;
        }
    };
    
    int main()
    {
        Stu *pstu=new Stu;
        delete pstu;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    结果展示:
    在这里插入图片描述

    四、new与delete的底层

    首先调用new
    在这里插入图片描述
    在底层调用的还是malloc分配的空间
    在这里插入图片描述
    malloc申请空间失败返回NULL;
    new申请空间失败抛出一个异常;
    在这里插入图片描述

    五、C++中new与malloc之间的联系与区别

    5.1 new与malloc之间的联系

    new的底层就是用malloc实现的。

    5.2 new与malloc之间的区别

    1. malloc如果申请空间失败返回NULL,new如果申请空间失败抛出异常 bad_alloc();
    2. new就是按类型开辟空间的,而malloc是按字节为单位开辟空间的。
    3. new/delete 是C++的关键字,malloc/free是库函数
    4. new可以在分配空间的同时进行初始化,malloc不可以。
    5. 当new分配的空间以int *pc = new int();,这种形式的时候,如果没有初始化,将用0进行初始化。如果是以int *pc = new int形式出现的,则将是随机值。
      malloc分配的空间如果没有初始化,是随机值,需要手动调用memset或者bzero函数来清空。
    6. new会根据类型自动计算分配空间的大小,malloc需要手动sizeof计算,传参。
    7. new是要什么类型,就返回什么类型的指针,malloc返回void *,需要进行强转。

    对自定义类型来讲:

    new 不仅开辟空间,还会调用自定类中的构造函数,malloc不会。
    delete 不仅释放空间,还会在释放空间前先调用类中析构函数,free不会。

  • 相关阅读:
    设计模式-装饰器模式
    软件测试2年,想去培训性能测试自动化测试,28岁了,要不要培训?
    C++指针解读(2)-- 指针变量
    工业设备数字孪生技术,解决方案系统平台案例
    SOT-23和SOT-223三极管及MOS管封装区别以及示意图
    Linux 安全 - Capabilities机制
    计算题概念算法
    Docker 安装 MySQL、Redis、Nginx
    Juniper SRX300系列 —— 防火墙常用命令
    【无标题】
  • 原文地址:https://blog.csdn.net/m0_65835264/article/details/126559032