NEW
在C++中,new和delete运算符用于动态分配和撤销内存的运算符。
•1、静态区: 全局变量。
•2、堆: 程序执行是分配的内存
•3、栈: 函数调用,局部变量。
举个例子int * pt ;//声明了一个pt指针,四个字节,放在栈里面的 •pt = new int;// new了一个int形的数据放在堆里面,再把这个数据的地址赋给pt。
#include<iostream> int main(void) { using namespace std; int nights=1001; int *pt=new int; *pt=1001; cout<<"night value= "; cout<<nights<<":location"<<&nights<<endl; cout<<"int "; cout<<"value="<<*pt<<":Location"<<pt<<endl; double *pd =new double; //allocate space for a double *pd=10000001.0; cout<<"double "; cout<<"value="<<*pd<<":location="<<pd<<endl; cout<<"location of pointer pd:"<<&pd<<endl; cout<<"size of pt="<<sizeof(pt); cout<<":size of *pt="<<sizeof(*pt)<<endl; cout<<"size of pd="<<sizeof(pd); cout<<":size of *pd="<<sizeof(*pd)<<endl; return 0; }
运行结果为:对于上面这段程序,可以这样来分析:我们开始定义的一个int型变量占4个字节,放在栈中,然后又new了4个字节放在堆中,并把堆的数据的首地址放在变量pt中,然后通过调用指针,也放了一个1001在堆中。所以当我们调用栈中的1001时,地址是栈的地址,档我们调用堆中1001时,存放的地址是堆的地址。所以两个地址是不一样的。
和上面的那个new一样分析,先new了一个8个字节的double型数据放在堆里面,然后在把这个数据的首地址赋给pd,程序要求输出的第三个地址就是这个数据的地址,即pd的值,要求输出的第4个地址是pd的地址,pd一般也是放在栈里,,所以这两个地址也是不一样的。
最后输出的pd和pt的字节大小都为4 ,这个就很好理解,因为在堆里面地址的大小都是一样的,在32位系统中均为4个字节,这个程序还需要注意的一个问题就是必须声明指针所指向的类型。因为pt和pd里的值都是储存的首地址,并没有指出地址的长度,*pd是8个字节的double值,*pt是4个字节的int值,打印*pd时,cout知道要读取多少字节以及如何解释它们。
•语法:•delete 指针变量;•举例:<span style="font-family:FangSong_GB2312;">int* p; p = new int; *p = 100; cout << *p << endl; delete p;</span>
注意,当一个指针接受delete操作后,它就又成了一个“指向不明”的指针。尽管我们可以猜测它还是指向“原来的房子”,然而,事实上,那座“房子”已经被delete “拆迁”掉了。这将会释放p的内存,但是不会删除p本身,我们可以将p重新分配内存块。
new [] 和 delete []
假如要编写一个程序,它是否使用数组,取决于运行时用户提供的信息,如果通过声明来创建数组,则在程序编译时将为它分配内存空间。不管程序最终是否使用数组,数组都在那里,它占用了内存。在编译时给数组分配内存被称为静态联编(static binding),意味着数组是在编译时加入到程序中的。但使用new时,如果程序在运行阶段需要数组,则创建它;如果不需要,则不创建。还可以在程序运行时选择数组的长度。意味着数组是在程序运行时创建时创建的,被称为动态联编(dynamic binding),这种数组叫做动态数组(dynamic array)。
new / delete 用于分配和释放单个变量的空间,而 new [] / delete[] 则用于分配连续多个变量的存间。new [] 语法:指针变量 = new 数据类型[元素个数]语法实例:int* p = new int[20];
首先,你需要迅速回想一下,如果是 int* p = new int(20); 那么该是什么作用?否则你很容易在事后把二者混了。实例中,用 new 申请分配了20个连续的整数所需的空间,即:20 * sizeof(int) = 80个字节。new int 只是分配了一个整数的内存空间,而 new int[N]却分配了N个整数的连续空间。看来,new[] 比 new “威力更猛”,所以,我们同样得记得:用 new [] 分配出空间,当不在需要时,必须及时调用 delete [] 来释放。
使用动态数组//分配了可以存放1000个int的连续内存空间: int* p = new int[1000]; //然后使用这些空间: …… //最后不需要了,及时释放: delete [] p;
程序输出:p3[1] is 0.5.#include<iostream> int main() { using namespace std; double * p3= new double[3]; p3[0]=0.2; p3[1]=0.5; p3[2]=0.8; cout<<"p3[1] is"<<p3[1]<<".\n"; p3=p3+1; cout<<"Now p3[0] is"<<p3[0]<<" and"; cout<<"p3[1] is"<<p3[1]<<".\n"; p3=p3-1; delete [] p3; return 0; }
Now p3[0] is 0.5 and p3[1] is 0.8.
从中可知,对于指针数组,第一个元素可以使用p3[0]表示,第二个元素可以使用p3[1]表示,第三个元素可以使用p3[2]表示,这样使用指针来访问动态数组就非常简单了。另外p3=p3+1,表示的是p3[0]现在指向数组第二个元素,最后只有将它减一后指针才能指向原来的值,给delete[]提供正确的地址。
总结不要使用delete来释放不是new分配的内存。不要使用delete释放同一个内存两次。如果使用new[]为数组分配内存,则应使用delete[]来释放。如果使用new[]为一个实体分配内存,则应使用delete(没有方括号)来释放。对空指针应用delete最安全。