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只能释放堆区的分配的内存。

 
原文地址:https://www.cnblogs.com/wangpfcnblogs/p/4604311.html