C++ new和delete

在c++中堆内存的分配与释放是通过new和delete来实现的,new和delete是两个操作符,无需头文件支持

new

new运算符

new运算符返回指向所分配类型对象的指针,new运算符首先向系统堆区申请足够的储存空间,如果申请成功,则再调用相应的默认构造函数,然后返回申请空间的地址

new的使用方法

int *p= new int ;//申请int
int *psome= new int[10];//申请int数组
A *q= new A;//申请自定义类型
A *qsome= new A[10];//申请自定义类型数组

delete

delete运算符

delete运算符首先执行默认析构函数,然后再回收分配的空间

delete的使用方法

delete p;//释放int
delete []psome;//释放int数组
delete q;//释放自定义类型
delete []qsome;//释放自定义类型数组

关于delete ptr和delete []ptr的差别

回归到new和delete上,当我们调用operator new[]/new来分配数组对象时,编译器时系统内部会增加4或者8字节的分配空间用来保存所分配的数组对象的数量,可以理解为下面这对pair

储存分配空间的字节数 分配空间的地址
4 0xabcd
例如分配以下空间

A *psome =new A[10];

此时如果使用delete psome,则只会调用一次析构函数,但是会收回所有分配的空间;而使用delete []psome,则会依次调用psome[0]-psome[9]的析构函数,然后再收回所有的分配空间

例如对于下面的代码

#include<iostream>
using namespace std;
int count=0;
class A{
public:
	int i;
	A();
	~A(); 
}; 
A::A(){//构造函数
	i=count++;
	cout<<"A::A() i="<<i<<endl;
}
A::~A(){//析构函数
	cout<<"A::~A() i="<<i<<endl;
}
int main()
{
	A *psome= new A[10];
	delete psome;
	//delete []psome;
    return 0 ;
}

运行得到结果如下

A::A() i=0//依次执行构造函数
A::A() i=1
A::A() i=2
A::A() i=3
A::A() i=4
A::A() i=5
A::A() i=6
A::A() i=7
A::A() i=8
A::A() i=9
A::~A() i=0//只执行依次析构函数,但空间全部回收

可以看到只执行了依次析构函数,因为对于delete而言psome所指对象只有一个对象

如果执行的是delete []psome,得到结果如下

A::A() i=0
A::A() i=1
A::A() i=2
A::A() i=3
A::A() i=4
A::A() i=5
A::A() i=6
A::A() i=7
A::A() i=8
A::A() i=9//执行10次构造函数
A::~A() i=9
A::~A() i=8
A::~A() i=7
A::~A() i=6
A::~A() i=5
A::~A() i=4
A::~A() i=3
A::~A() i=2
A::~A() i=1
A::~A() i=0//执行10次析构函数

可以看到执行了10次析构函数,并且是从最后一个元素开始向前执行的,此时delete知道psome所指地址有多个对象,会通过上面的pair计算要执行析构函数的次数并依次执行

因此就结论而言,new/delete 、new []/delete[] 最好要配对使用

Tips

1.不要使用delete去释放没有new的内存

2.不要重复delete

3.delete[]和new[]配套使用 ,delete和new配套使用

4.delete空指针是安全的(体现完备性)

posted @ 2020-06-06 16:50  海物chinono  阅读(149)  评论(0)    收藏  举报