[c++04]delete和delete[]的区别

Posted AIplusX

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[c++04]delete和delete[]的区别相关的知识,希望对你有一定的参考价值。

写在前面

今天来讲一些 d e l e t e [ ] delete[] delete[] d e l e t e delete delete的相关知识,什么情况下我们应该使用 d e l e t e [ ] delete[] delete[],什么情况下我们应该 d e l e t e delete delete,以及错误使用会带来的问题。

正文

首先呢,我们需要构建一个简单的 A A A类,然后对其做文章,详细看下面我的测试程序:

下面 m o r e more more命令显示的就是.cpp文件里面的内容,可以看到我还是利用静态的全局变量记录类的构造函数和析构函数的调用情况。然后我用 n e w ∗ p = n e w A [ 10 ] new *p = new A[10] newp=newA[10]来在堆里面申请了10个 A A A类对象大小的内存,之后啥也没干,啥 d e l e t e delete delete也没用,直接结束了程序。

那么程序执行的结果是什么样子的呢?就是上面显示的结果了,可以看到,每个类的构造函数都得到了调用,但是却没有调用析构函数,按照道理来说,对象的生命周期结束之后,也应该会被系统自动回收内存呀,应该是下面这个结果:


测试程序:

细心的朋友应该已经发现了,对象生成的方式不一样,在第二种情况下,我没用 n e w new new生成对象,而是直接按照类名+对象名的方式生成了对象,此时对象是存放在栈里的,所以在栈内程序结束之后析构函数会被自动调用。

堆里的对象不会自动被析构,所以说手动 d e l e t e delete delete掉堆里面申请的内存是非常重要的。那么接下来看看如果正确回收 n e w new new申请出来的对象数组内存,先看一下测试程序:

结果:

上述测试程序就是正确的释放对象数组内存的方式。

那么讲完正确的,我们来看看如果错误释放内存会发生什么呢?让我们来修改一下测试程序:

在这个测试程序里面,我给 A A A类设计了一个 s e t _ j ( ) set\\_j() set_j()的函数,用来修改成员变量 j j j的数值。我的目的是为了测试一下,对象在构造和析构时候的顺序关系。让我们来运行一下这段程序:


可以看到,在构造的时候我是按照 j j j的数值从1到10来构造对象的,但是在析构的时候却是第10个对象先被析构,然后再是第9个,按照这个顺序进行析构,直到第1个对象被析构为止。示意图如下所示:

那么在这种情况下,用的是错误的 d e l e t e delete delete而不是正确的 d e l e t e [ ] delete[] delete[]的话会发生什么情况呢?我猜分配内存的指针可能是会指向数组里的最后一个对象,然后因为只是 d e l e t e delete delete,所以编译器会尝试释放一块以指针 p p p为首地址的,大小为10个对象内存大小的地址,但是因为没用 d e l e t e [ ] delete[] delete[],所以程序可能会向后去释放内存,也就是非法的内存,然后程序会报错。

接下来让我们来试试这个事情:

可以看到,程序确实发生了崩溃,而且也是首先释放了第10个对象之后程序就崩溃了。但是,具体的崩溃原因并不能在这里体现出来。

因为异常我还没有做过测试,所以我就不再继续了,大家记住 d e l e t e delete delete d e l t e [ ] delte[] delte[]正确使用的正确性,以及错误使用的后果就是我这篇文章的目的啦。

要想知道程序崩溃的真正原因,可以从以下2个方面下手:

1:阅读实现源码(强烈推荐);

2:利用异常机制进行测试;

以上是关于[c++04]delete和delete[]的区别的主要内容,如果未能解决你的问题,请参考以下文章

c的free和c++的delete的区别

delete和delete[]的区别(转载)

C++中delete和delete[]的区别

C 中的 free 和 C++ 中的 delete 之间的区别?

C++中delete与 delete []区别

malloc/free与new/delete的区别与联系