版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YL970302/article/details/90106521
一、什么时候用new[]申请,可以用delete释放
1、在C++中,把单个元素的内存开辟释放和数组的内存开辟释放是分开的。因为在C++里面,开辟内存和构造对象是一起发生的,析构对象和释放内存是一起发生的
int *a = new int; //delete a 或 delete[] 都可以
int *p = new int[]; //delete p 或 delete p[] 都可以
也就是说上述两种情况的释放效果相同,原因在于它们是内置类型,内置类型是没有所谓的构造和析构的。对于内置类型来说,内存大小已经确定,系统可以记忆并且进行管理,在析构的时候,系统并不会调用析构函数,它直接通过指针可以获取实际分配的内存空间
2、对于没有析构函数的自定义类类型
class Test
{
public:
Test(){}
private:
int _data;
};
Test *p = new Test; delete p;
Test *p = new Test; delete []p;
Test *p = new Test[10]; delete []p;
Test *p = new Test[10]; delete p;
上述的4条代码也是不存在任何问题的,因为这个类没有提供析构函数,也就是说Test类对象不需要进行任何有效的析构,那么delete就只剩完成free的功能就行了
总结:综上两点我们可以得出结论,在使用new开辟内存的时候,如果是内置类型或者是自定义类类型没有提供析构函数的情况下,用new[]分配的内存空间可以使用delete和delete[]两种释放内存方式来释放
3、
class Test
{
public:
Test(){}
~Test(){}
private:
int _data;
};
Test *p = new Test; delete p; //ok
Test *p = new Test; delete []p; //程序崩溃
Test *p = new Test[10]; delete []p;//ok
Test *p = new Test[10]; delete p; //程序崩溃
此时有了自定义的析构函数我们对上面的四条代码进行分析
Test *p = new Test; delete []p; //程序崩溃
这段代码在内存上开辟了4字节的内存,如下:
而delete[]释放代码的位置其实是下面这张图:
为什么它为什么会减去4个字节开始释放内存呢?因为定义了析构函数,在释放内存在前需要在内存中析构对象,你写个delete[]p,编译器就认为这里有很多对象要析构,有多少个呢?记录对象个数的数字就在对象内存上面的4个字节存放,因此它从第二幅图的那个位置开始释放,如果按第一个图的代码写肯定是要发生错误的
下面这段代码的内存分配
Test *p = new Test[10]; delete p; //程序崩溃
这样错误就一目了然了吧
总结:(delete和delete[]的区别)
- delete p; //仅释放了p指针指向的全部内存空间,但是只调用了p[0]对象的析构函数,剩下的从p[1]到p[9]这9个用户自行分配的对应内存空间将不能释放,从而造成内存泄漏
- delete []p;//调用使用类对象的析构函数释放自己分配内存空间,并且释放了p指针指向的全部内存空间(逐一释放数组中每个对象的内存)