delete和delete[]的区别以及什么时候用new[]申请可以用delete来释放

版权声明:本文为博主原创文章,未经博主允许不得转载。 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指针指向的全部内存空间(逐一释放数组中每个对象的内存)

猜你喜欢

转载自blog.csdn.net/YL970302/article/details/90106521