• C++的new和delete


    一,new和delete:

    1new是操作符,不是函数,malloc是函数。

    2)基本数据类型(int floatdoublechar),free, malloc, new,delete 效果一致。

    3delete ,free对于基本数据类型,释放,释放两次都会出错。

    4free之后,指针的值不会改变,delete之后,指针的值会改变(我的电脑上每次delete之后,指针的值变成了0000 8123),free之后的指针的值没有改变,打印出来的是垃圾值free之后,为了避免迷途指针,最好将指针设置为空指针(nullptr)。

    5如果是基本数据类型 new 是不会调用构造函数,delete 时不会调用析构函数。

    如果是结构类型,new会调用构造函数,delete会调用析构函数。

    6)基本数据类型 数组,deletedelete[]一致;基本数据类型,可以互相混合使用。

    7复合数据类型(delete  delete[]不能混合使用)

    例如:mydata *p(new mydata);   delete p;

    mydata *p(new mydata[10]);    delete[] p;

    8)单个堆上的对象,不可以用delete [],反复delete,下面delet代码是错误,只用能delete p,不能用delete [] p.

    mydata *p(new mydata);

    delete [ ]  p;//单个堆上的对象,不可以用 delete [],delete[]程序会报错

    #include<iostream>
    using namespace std;
    
    void main2()
    {
        int *p1 = new int(4);//指向一个变量
        int *p2 = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };//指向数组
        delete p1;//delete p1    int *p1 = new int(4);
        delete[] p2;//delete[] p2  int *p2 = new int[10]{ 1,2,3,4,5,6,7,8,9,0 };
        
        cin.get();
    }
    
    //数组new和初始化
    void main3() { int *p = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; cout << p << endl; cout << "--------------" << endl; delete[] p; cin.get(); }

    //基本数据类型new及初始化
    void main4() { int *p1 = new int(4); cout << p1 << endl; cout << "--------------" << endl; delete p1;//delete[] p1; cin.get(); }
    class mydata { public: mydata() //构造函数 { cout << "create" << endl; } ~mydata()//析构函数 { cout << "delete" << endl; } };
    void main() { mydata *p(new mydata); delete p; //mydata *p(new mydata); //delete []p;//单个堆上的对象,不可以 delete [],反复delete mydata *p(new mydata[10]); delete []p;//异常 cin.get(); }
    二,定位new运算符:
    定位new运算符是new运算符的一种变体。通常new是在堆区来开辟内存的,如果需要可以new还可以在栈区和静态区开辟空间。
    要使用定位new运算符,要包含new头文件#include<new>。
    #include <iostream>
    #include <new>
    
    using namespace std;
    
    const int BUF = 512;
    const int N = 5;
    char buffer[BUF];
    
    int main()
    {
        double *p1, *p2;
    
        cout << "calling new and placement new " << endl;
        p1 = new double[N];
        p2 = new (buffer) double[N];
        for (int i = 0; i < N; i++)
        {
            p2[i] = p1[i] = 1000 + 10.0*i;
        }
        cout << "heap:"<<p1<< "      static:"<<(void*)buffer << endl;
        cout << "memory contents:" << endl;
        for (int i = 0; i < N;i++)
        {
            cout <<" p1  "<< p1[i] << " at " << &p1[i] << ";   ";
            cout << " p2  "<<p2[i] << " at " << &p2[i] << endl;
        }
    
        cout << "   " << endl;
        cout << "calling new and placement new a second time" << endl;
        double *p3, *p4;
        p3 = new double[N];
        p4 = new (buffer) double[N];//重写数据
        for (int i = 0; i < N; i++)
        {
            p4[i] = p3[i] = 1000 + 50.0*i;
        }
    
        cout << "memory contents:" << endl;
        for (int i = 0; i < N; i++)
        {
            cout << "p3  "<<p3[i] << " at " << &p3[i] << ";   ";
            cout << "p4  " << p4[i] << " at " << &p4[i] << endl;
        }
    
        cout << "   " << endl;
        cout << "calling new and placement new a third time" << endl;
        delete [] p1;
        p1 = new double[N];
        p2 = new(buffer + N*sizeof(double)) double[N];
        for (int i = 0; i < N; i++)
        {
            p2[i] = p1[i] = 1000 + 70.0*i;
        }
        
        cout << "memory contents:" << endl;
    
        for (int i = 0; i < N; i++)
        {
            cout <<"p1 "<< p1[i] << " at " << &p1[i] << ";   ";
            cout << "p2"<<p2[i] << " at " << &p2[i] << endl;
        }
    
        delete[]p1;
        delete[]p3;
        
    
        cin.get();
        return 0;
    }

    运行结果:

    calling new and placement new
    heap:007AB2F8      static:01380320
    memory contents:
     p1  1000 at 007AB2F8;    p2  1000 at 01380320
     p1  1010 at 007AB300;    p2  1010 at 01380328
     p1  1020 at 007AB308;    p2  1020 at 01380330
     p1  1030 at 007AB310;    p2  1030 at 01380338
     p1  1040 at 007AB318;    p2  1040 at 01380340
    
    calling new and placement new a second time
    memory contents:
    p3  1000 at 007AB500;   p4  1000 at 01380320
    p3  1050 at 007AB508;   p4  1050 at 01380328
    p3  1100 at 007AB510;   p4  1100 at 01380330
    p3  1150 at 007AB518;   p4  1150 at 01380338
    p3  1200 at 007AB520;   p4  1200 at 01380340
    
    calling new and placement new a third time
    memory contents:
    p1 1000 at 007AB2F8;   p21000 at 01380348
    p1 1070 at 007AB300;   p21070 at 01380350
    p1 1140 at 007AB308;   p21140 at 01380358
    p1 1210 at 007AB310;   p21210 at 01380360
    p1 1280 at 007AB318;   p21280 at 01380368

    定位new运算符,将p2放在了数组buffer中,p2和buffer的地址都是01380320;然而他们的类型不同,p2是double的指针,buffer是char的指针。所以用void*对buffer进行类型转换,不然buffer打印出来的是一个字符。

    最后,不能直接delete [  ] p2,由于buffer指定的是内存的静态内存,而delete只能释放堆区的分配的内存。

     
  • 相关阅读:
    使用 Prism.js 实现代码高亮
    Win10系统如何删除网络及修改网络名称
    CRT和PEM格式证书转换
    CentOS如何修改主机名
    crt格式证书转换为pem格式
    CentOS安装wget命令
    自适应(响应式)网页中的几个关键分辨率
    java中的I/O流学习(1)
    有种心态,我不知该如何表达
    java学习笔记—Scanner
  • 原文地址:https://www.cnblogs.com/wangpfcnblogs/p/4604311.html
Copyright © 2020-2023  润新知