new和delete的用法,参考[1]
- new() 分配这种类型的一个大小的内存空间,并以括号中的值来初始化这个变量;
- new[] 分配这种类型的n个大小的内存空间,并用默认构造函数来初始化这些变量;
使用举例:
1、new和new[]
#include <iostream> #include <string.h> using namespace std; int main(){ //char * p=new char("Hello"); //error,分配一个char(1字节)的空间, //用"Hello"来初始化,这明显不对 char* p=new char[6]; //p="Hello"; //不能将字符串直接赋值给该字符指针p,原因是: //指针p指向的是字符串的第一个字符,只能用下面的 //strcpy strcpy(p,"Hello"); cout<<*p<<endl; //只是输出p指向的字符串的第一个字符! cout<<p<<endl; //输出p指向的字符串! delete[] p; return 0; }输出结果:
H Hello
2、new的同时初始化:
int *a = new int ; //将一个int类型的地址赋值给整型指针a. int *a = new int(5);//作用同上,但是同时将指针指向的内容赋值为5
3、当使用new运算符定义一个多维数组变量或数组对象时,它产生一个指向数组第一个元素的指针,返回的类型保持了除最左边维数外的所有维数。例如:
int *p1 = new int[10]; //返回的是一个指向int的指针int*,开辟一个大小为10的整形数组空间; int (*p2)[10] = new int[2][10]; //new了一个二维数组, 去掉最左边那一维[2], 剩下int[10], 所以返回的是一个指向int[10]这种一维数组的指针int (*)[10]. int (*p3)[2][10] = new int[5][2][10]; //new了一个三维数组, 去掉最左边那一维[5], 还有int[2][10], 所以返回的是一个指向二维数组int[2][10]这种类型的指针int (*)[2][10].
4、delete
int *a = new int; delete a; //释放单个int的空间 int *a = new int[5]; delete [] a; //释放int数组空间 int (*p2)[10] = new int[2][10]; delete [] p2; //不管数组是几维的,delete的形式都是一样的;
5、new运算符
最常用的是作为运算符的new,比如:
string *str = new string(“test new”);作为运算符,new和sizeof一样,是C 内置的,你不能对它做任何的改变,除了使用它。
new会在堆上分配一块内存,并会 自动调用类的构造函数。
6、切记切记,new/delete、new[]/delete[] 要配套使用。至于原因,参见[2][3]。delete掉一块内存,具体的是执行了什么操作呢?
如果说这块内存总是保存的普通的变量,此时编译器只会释放此指针所指向的内存空间,而不会破坏这个指针本身,指针本身的值还是原来的值,而指针指向的内容可能变为随机数,例如-572662307(vs中),也可能保持不变(gcc中)
如果说这块内存中本身还存在指针,那么delete后这块内存中的指针本身的值可能变为随机数,比如:-572662307(意味着此时该指针的指向发生了变化),可能保持不变(gcc中)。而指向这块内存的指针本身不会变,这是确定的。总之很神奇,是和编译器相关的。
不管在哪个编译器中,delete掉一块内存之后,记得把指向这块内存的指针赋值为NULL,否则的话会很危险,详见delete *p之后一定要加上: p=NULL。比如说程序在之后的代码中又new了内存,此时分配的内存很可能就是刚刚delete掉的内存,那么之前指向这块内存的指针就拥有修改这块内存中数据的能力,而这是我们不希望的,所以当delete的时候,一定记得顺手把此时的指针指向NULL。
参考:
[1] new与delete的基础用法
[2] 浅谈 C++ 中的 new/delete 和 new[]/delete[]背后的机制