• new/delete和malloc/free的区别


    区别:

    1. new/delete是C++里才有的,而new/delete与malloc/free一个显著的区别在于,new是建造一个对象,并调用对象的构造函数来初始化对象,其实在所有的new操作过程中,总是分为两步的:第一步是申请内存,第二步则是调用构造函数初始化对象。同样,在调用delete的时候,需要先调用析构函数,然后在销毁堆内存。
         2. new/delete通常来说是操作符,就是"+","-"一样。
         3. new/delete是可以重载的,而重载之后,就成为了函数。
         4. malloc在申请内存的时候,必须要提供申请的长度,而返回的指针是void*型,必须要强转才能成为需要的类型。
         5. 当new/delete在类中被重载的时候,可以自定义申请过程,比如记录所申请内存的总长度,以及跟踪每个对象的指针。
         6. C++默认的new/delete操作符内部,其实也调用了malloc/free这两个函数。

         7.对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

         8.C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数, new 不止是分配内存,而且会调用类的构造函数,同理delete会调用类的析构函数,而malloc则只分配内存,不会进行初始化类成员的工作,同样free也不会调用析构函数。 


    共同点:
         1. 都必须配对使用,这里的配对使用,可不能理解为一个new/malloc就对应一个delete/free,而是指在作用域内,new/malloc所申请的内存,必须被有效释放,否则将会导致内存泄露,至于内存泄露的检查方法,我们推荐的工具是大家众所周知的BoundsChecker,至于如何使用BoundsChecker,我们将在以后撰文详解。
         2. 都是申请内存,释放内存,free和delete可以释放NULL指针。
    注意点:
         1. new/delete与malloc/free不能混合使用,有些人对这个观点持怀疑态度,因为在很多时候,他混合使用之后也没有严重的后遗症,那是因为在通常情况下,new操作符的确调用了malloc这个函数,所以free函数可以正常的释放new出来的内存空间。但这并不能保证所有的new操作符都是调用C++的new的原始操作符,而最常见的是,在类中,我们是可以重载new这个操作符的,这样的话,如果一但在operator=new()函数中调用了其它的申请函数的话东西,free将无法正常工作,或者说也将导致内存泄露。

    举几个简单的例子吧:

    class CTest
    {
    public:
        CTest();
        ~CTest();
    
    private:
        int* __m_pn;
    };
    
    CTest::CTest()
    {
        __m_pn = new int[128]; assert(__m_pn);
    }
    
    CTest::~CTest()
    {
        assert(__m_pn);
        delete[] __m_pn;
        __m_pn = NULL;
    }
    
    int main()
    {
        int* pn = (int*)malloc(sizeof(int));
        *pn = 15;
        free(pn);
        pn = NULL; // 置空
        free(pn); // OK,没有问题
        double* pd = new double;
        *pd = 212.211;
        delete = pd;
        short* ps = new short[128]; // new出一个数组来
        ps[1] = 1231;
        ps[11] = 1111;
        delete[] ps; // 请注意delete的语法。
        CTest* pTest = new CTest; // new出一个对象,并初始化
        // …… 干活
        delete pTest; // 析构,释放内存
    }

    // 以下是一个重载new操作符的例子,一般来说是不会用到的,除非要设计一个编译器之类的东西。

    class Sample
    {
    public:
        static CSample* operator= new()
        {
            CSample* p = (CSample*)malloc(size(Sample));
            __m_nCount++; // 记录这个类被申请的对象的数目
            return p;
        }
    
    private:
        static int __m_nCount_;
    };
  • 相关阅读:
    1105 Spiral Matrix
    Spring Boot 单元测试
    第一个 Spring Boot 应用程序
    Spring Boot 优缺点
    Spring Boot 简介
    第一个 Spring 应用程序
    Spring 体系结构
    Spring 与 IoC
    Spring 的特点
    Spring 简介
  • 原文地址:https://www.cnblogs.com/menghuizuotian/p/3755900.html
Copyright © 2020-2023  润新知