我们定义对象时,Test t; 这是静态存储分配,由系统在栈空间给我们分配好了;
有些情况要求运行时分配,这就是动态存储分配,在堆中进行;
在C++中用new和delete来对空间进行管理。
new开辟空间返回值是一个指针。
- C语言中通过malloc来申请空间,不管变量还是数组都一样,通过字节来计算申请空间的大小。
C++中的new不同;
int *a = new int;(变量)
int *a = new int[10];(数组) new开辟空间不考虑字节个数。
-
C++中申请空间时还能初始化。 int *a = new int(10); 但不能对申请数组空间进行初始化,所以必须有默认的构造函数;
-
释放空间
delete a;
delete []a; //释放空间;[]中的数字可以不写,就是写多少都不影响。
原因如下:
在C++中申请的是数组空间,在释放时必须写上[], 不然delete a; 将会发生内存泄漏!!!
- C++中在进行new开辟空间时,做两件事,先申请空间,在调用构造函数。
delete也做两件事:先调用析构函数,在释放其所指向的空间。
void *ps= new String("abc");
delete ps; 如何评价?
void,指针所指向的类型不定,所以在delete时,不调用析构函数,此时,将发生内存泄漏;
只有指针所指向的空间类型定了,delete时才调用析构函数。
String *ps= new String("abc");
delete ps; 如何评价?
此时整个过程:先开辟空间 -->再调构造函数.....调析构函数--->释放ps所指向的空间.
operator new Constructor //先申请空间,在调用构造函数。(缺一不可)
delete operator:先调用析构函数,在释放其所指向的空间;(缺一不可)
我们可以改变如何分配内存,也就是开辟空间的过程。
new的重载:
- 返回值必须为void*类型;
- 第一个参数必须为size_t;
void* operator new(size_t sz){
void *p = malloc(sz);
return p;
}
void* operator new[](size_t sz){
void *p = malloc(sz); //重载,对数组申请空间
return p;
}
...........
void operator delete(void *p){
free(p);
}
void operator delete[](void *p){
free(p); //重载,对数组释放空间
}
重载了new,就必须重载delete,因为malloc开辟空间和free释放空间必须一一对应。
operator new只负责开辟空间,要是函数中有,调用离自己最近的(类内->全局->系统)。
定位new 不开辟新的空间,对已有的空间进行赋值;
new(p)int(10); //p是一个地址,默认下标是0,10是要赋的值。
#include<iostream>
using namespace std;
void* operator new(size_t sz, int *d, int pos){ //operator new 的重载
return &d[pos]; //d + pos;
}
int main(void){
int ar[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,};
new(ar, 1)int(10); //定位new,不开辟新的空间。
//将10放到下标为0的地方;
cout<<ar[1]<<endl;
return 0;
}
结果如下:
原创文章链接:C++从零入门学习系列(14)---new和delete