一,new和delete:
(1)new是操作符,不是函数,malloc是函数。
(2)基本数据类型(int ,float,double,char),free, malloc, new,delete 效果一致。
(3)delete ,free对于基本数据类型,释放,释放两次都会出错。
(4)free之后,指针的值不会改变,delete之后,指针的值会改变(我的电脑上每次delete之后,指针的值变成了0000 8123),而free之后的指针的值没有改变,打印出来的是垃圾值。free之后,为了避免迷途指针,最好将指针设置为空指针(nullptr)。
(5)如果是基本数据类型 new 是不会调用构造函数,delete 时不会调用析构函数。
如果是结构类型,new会调用构造函数,delete会调用析构函数。
(6)基本数据类型 数组,delete,delete[]一致;基本数据类型,可以互相混合使用。
(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(); }
#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只能释放堆区的分配的内存。