IE盒子

搜索
查看: 118|回复: 0

c++基础梳理(六):C++中的new和delete

[复制链接]

4

主题

10

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2023-4-28 12:36:33 | 显示全部楼层 |阅读模式
1. 动态内存分配

1.1 基础数据类型

开辟: 类型 指针变量 = new 类型(常量) 其中常量为初始化的值,可要可不要;
释放:       delete 指针变量;
//test1.cpp
#include <iostream>

using namespace std;

int main()
{
   
    /* c++ new - delete */
    int *p1 = new int; // 开辟一个存放int数据类型的空间地址,返回指向该地址的指针给p;
    char *p2 = new char;
    int *p3 = new int(5);// 开辟一个存放int数据类型的内存地址,该int型数据的初值为5;

    delete p1;
    delete p2;
    delete p3;


     /* c对比: malloc- free */
    int *p4 = (int *)malloc(sizeof(int)); // 开辟一段int类型的空间地址
    char *p5 = (char *)malloc(sizeof(char)); // 开辟一段char类型的空间地址
    int *p6 = (int *)malloc(sizeof(int));
    *p6 = 5; //开辟一段存放int类型数据的空间地址,并赋值为5;
    free(p4);
    free(p5);
    free(p6);

}
1.2 数组

开辟: 类型 指针变量 = new 类型[表达式]
释放: delete [] 指针变量

  • 用new分配数组空间时,不能赋初值;
  • 如果内存空间不够,new失败时,会返回一个空指针NULL;
//test2.cpp
#include <iostream>

using namespace std;

int main()
{
   
    /* c++ new - delete */
    int *p1 = new int[5]; // 开辟存放5个int类型数据的数据空间
    p1[0] = 2;
    char *p2 = new char[10];
   
    delete [] p1;
    delete [] p2;

     /* c对比: malloc- free */
    int *p3 = (int *)malloc(sizeof(int)*5); // 开辟存放5个int类型数据的数据空间
    p3[0] = 2;
    char *p4 = (char *)malloc(sizeof(char) * 10 +1);  //别忘记字符串最后有个结尾符号,多占用一位;

    free(p3);
    free(p4);
}
1.3 类


  • new 开辟类的空间时,会调用构造函数,所以可以进行初始化
//test3.cpp
#include <iostream>

using namespace std;

class Student
{
    public:
        Student(int age)
        {
            age_ = age;
        }
    private:
        int age_;


};

class A
{
    public:
        void PrintAge();
    private:
     int age_;

};

int main()
{
   
    /* c++ new - delete */
    Student *p1 = new Student(21); // new 一个student的对象,并用21进行初始化;
    delete p1;

    A *p2 = new A;//是否初始化取决于该对象的构造函数
    delete p2;

    char *p3 = "hello world";
    //p3 = new A;
   // delete p3;  // error delete 非new初始化的指针,

}
1.4 使用注意事项


  • delete 用来释放new初始化的指针,如果一个指针不是new初始化的,不要用delete去释放;
  • new 和delete会调用构造和析构函数,如果类有多个构造和析构函数,遵循函数重载的规则,调用也遵循函数重载的规则;
  • new是在堆上分配内存;
  • delete 后最好将指针赋值为NULL,因为delete并不是将指针删掉,而是释放指针所指向的那块内存,delete后其实该指针还是指向了该内存空间,如果没有清零,再次使用会有异常;
//test4.cpp
#include <iostream>

using namespace std;

class Student
{
    public:
        Student(int age)
        {
            age_ = age;
        }
    private:
        int age_;


};

class A
{
    public:
        void PrintAge();
    private:
     int age_;

};

int main()
{
    /* c++ new - delete */
    Student *p1 = new Student(21); // new 一个student的对象,并用21进行初始化;
    cout << "p1 before delete address: " << p1 << endl;
    delete p1;
    cout << "p1 after delete address: " << p1 << endl;
    cout << "==== end ====" << endl;
}


2. malloc -free 与new-delete 区别和联系

2.1 区别


  • malloc 不会调用构造函数, new会调用构造函数;
  • free 不会调用析构函数,delete会自动调用析构函数,完成内存释放的善后工作;
  • new 和delete是运算符,不是函数,因此执行效率更高,malloc和free是函数;
//test5.cpp
#include <iostream>

using namespace std;

class Student
{
    public:
        Student(int age)
        {
            age_ = age;
            cout << "构造函数" << endl;
        }
        ~Student()
        {
            cout << "析构函数" << endl;
        }
    private:
        int age_;


};

class A
{
    public:
        void PrintAge();
    private:
     int age_;

};

int main()
{
    /* c++ new - delete */
    cout << "c++ new - delete" << endl;
    Student *p1 = new Student(21); // new 一个student的对象,并用21进行初始化;
    delete p1;
   
    /* c malloc - free */
    cout << "c malloc - free" << endl;
   Student *p2 = (Student *)malloc(sizeof(Student));
   free(p2);

   cout << "===== end =====" << endl;

}


2.2 混合使用


  • malloc 建立,delete 释放: 对类的内存申请没有调用构造函数;
//test6.cpp
#include <iostream>

using namespace std;

class Student
{
    public:
        Student(int age)
        {
            age_ = age;
            cout << "构造函数" << endl;
        }
        ~Student()
        {
            cout << "析构函数" << endl;
        }
   
    int age_ = 16;


};

class A
{
    public:
        void PrintAge();
    private:
     int age_;

};

int main()
{
    /* 基础数据类型 */
    int *p1 = (int *)malloc(sizeof(int));
    delete p1;

    /* 数组 */
    int *p2 = (int *)malloc(sizeof(int) * 10);
    delete [] p2;

    /* 类 */
    Student *p3 = (Student *) malloc(sizeof(Student)); //没有调用构造函数
    cout << "p3 age: " << p3->age_ << endl;
    delete p3;
   

   cout << "===== end =====" << endl;

}



  • new 建立,free释放: 只有构造,没有析构
//test7.cpp
#include <iostream>

using namespace std;

class Student
{
    public:
        Student(int age)
        {
            age_ = age;
            cout << "构造函数" << endl;
        }
        ~Student()
        {
            cout << "析构函数" << endl;
        }
   
    int age_ = 16;


};

class A
{
    public:
        void PrintAge();
    private:
     int age_;

};

int main()
{
    /* 基础数据类型 */

    int *p1 = new int;
    free(p1);

    /* 数组 */


    int *p2 = new int[10];
    free(p2);

    /* 类 */
   Student *p3 = new Student(14);
   free(p3);
   

   cout << "===== end =====" << endl;

}


结论: 对于基础数据类型,混合使用问题不大,对于类,由于malloc-free不会调用构造和析构函数,因此还是用new和delete比较好;
3. 其他

参考:https://www.bilibili.com/video/BV1ss411A7Dm/?spm_id_from=333.337.search-card.all.click&vd_source=cc4584013fce7bf78252de67c6bd4d86
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表