C++new与定位new
1.new运算符和new[]运算符
new运算符会根据所给类型动态分配内存(在堆中),然后返回首地址
A.动态分配基本类型和基本类型的数组
//基本类型
//仅分配空间,不初始化 typeName * pointer = new typeName; //例: int * pint = new int; //分配空间,同时初始化 typeName * pointer = new typeName(value); //例: int * pint = new int(3); //分配一个整型空间,初始化为3 //基本类型数组 typeName * parray = new typeName[SIZE]; //例: int * parray = new int[5]; //分配长度为5的动态整型数组
B.动态分配类对象
//分配内存后调用无参构造 //分配内存后调用有参数默认值的有参构造 className * pobj = new className(); //分配内存后调用有参构造 className * pobj = new className(参数列表);
C.使用delete释放
- 通过new运算符分配的内存,使用delete释放
- 通过new[]运算符分配的内存(数组),通过delete[]释放
- 动态分配的内存只可以释放一次
2.定位new
定位new可以在指定的位置分配内存
A.和普通new的区别
需要在指定一个分配的位置,也就是说从哪里开始分配
例: char buffer[256]; int * pint = new(buffer) int; int * parray = new(buferr) int[5]; A * pa = new(buffer) A(); //A为自定义的类
B.一个问题
int main() { char buffer[256]; cout << (void *)buffer << endl; int * pint = new(buffer) int; cout << pint << endl; int * parray = new(buffer) int[5]; cout << parray << endl; A * pa = new(buffer) A(); cout << parray << endl; return 0; }
输出: 004FFC54 004FFC54 004FFC54 004FFC54 可见,定位的new并不智能,永远只从我们指定的地方开始
解决:
int main() { char buffer[256]; cout << (void *)buffer << endl; char *p = buffer; int * pint = new(p) int; p += sizeof(int); cout << pint << endl; int * parray = new(p) int[5]; p += sizeof(int[5]); cout << parray << endl; A * pa = new(p) A(); p += sizeof(A); cout << pa << endl; pa->~A(); return 0; }
C.释放——放buffer即可
I>基础类型
由于我们是在buffer已经分配的基础上分配,所以,释放buffer即可
上述例子中,buffer在代码块结束后,会自动释放;
如果buffer通过new分配,则需要使用delete释放
II>类对象
可能大家注意到了,上述例子中,我们显式调用了对象的析构函数。 类在释放自己的空间前,会自动调用析构函数,但是在定位new这里,不能通过delete 语句释放对象,所以,对象就不能隐式的调用析构函数,需要在buffer释放前,显式的调用析构函数