博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++中delete与delete[]
阅读量:7041 次
发布时间:2019-06-28

本文共 1421 字,大约阅读时间需要 4 分钟。

这篇文章是CSDN C++论坛中多次讨论到的一个问题。

先看下面程序:

#include 
using namespace std; #include
int main() {
int *p=new int[5]; //delete p; delete []p; p=NULL; //string *p=new string[5]; //delete p; //delete []p; //p=NULL; return 0; }

对于int类型和string类型,delete p和delete []p编译器(vc6.0)会有不一样的结果,对于int类型delete p和delete []p均可以编译运行,而 对于string类型,delete p运行

后程序会崩溃。

下面是对这个问题网友的意见与我的总结:

(1)delete 与delete[]都会释放所有内存,它们的不同点仅在于,根据得到的类型信息是单个指针还是指向数组的指针,来决定调用析构函数的次数。而编译器对所要删除的那个指针到底是指向的单一对象还是对象数组的判断依据就是"[]"的有无。若有'[]'编译器得到的类型信息就是指向数组的指针,然后调用多次析构函数;若没有‘[]’编译器得到的类型信息就是单个指针,只调用一次析构函数。

其实delete操作本身就是做两件事:
<1> 针对此处内存调用析构函数
<2> 然后释放该处内存。
(详见《Effective C++》(2nd)item 5 或 (3rd)item 16)。

 

(2)vc6.0和vs05中,delete和delete[]语句都是调用operator delete(),在vs05中调试,在跟进operator delete()中,可看到有这样一句“_free_dbg( pUserData, pHead->nBlockUse );”而free要正确工作,有一个必要前提,即传给它的地址确实是当初申请的内存首地址,否则,会出现assert错误。即在重载delete操作符后,某种情况下发现delete操作的指针地址不同于new操作所获取的地址。从而出现assert错误,程序崩溃。

(3)在VC中,对于有显式析构函数的对象, 在分配数组时其前会有一个4字节前缀用来保存数组元素个数. 如果用delete来释放数组, 就会导致释放的内存地址与分配时的内存地址出现4字节偏差, 而导致灾难性的错误.

(4)那么什么情况下,二者操作的指针地址不匹配呢?
经过反复实验测试,发现只要对象类型定义有显式析构函数,那么这个4字节就肯定存在。也就是说,哪怕是我们自定义的一个类类型对象,只要我们没有为这个类定义析构函数,那么这个4字节问题就不会出现;那么该用delete[]的时候,用delete也不会报错;那么该用delete的时候,用delete[]也不会报错,那么...
本论题,由于内置类型没有析构函数,而string有析构函数,这样一种巧合,而把问题局限在了内置类型与自定义类型这样的分类范围上。所以我们这个问题准确的说,应该是显式析构函数的存在影响了delete与delete[]的处理。

 

(5)一句话:该用delete[]时莫省略,这是C++标准。

 

原帖如下:

(1)

(2)

(3)

转载地址:http://cuhal.baihongyu.com/

你可能感兴趣的文章
nginx的日志分析
查看>>
ListView原理
查看>>
python--------------内置函数
查看>>
Scapy基础学习之中的一个
查看>>
http请求头详解
查看>>
SVNserver搭建
查看>>
Java基础(九):抽象类
查看>>
Unix:关于一个file在file system和disk中占用空间
查看>>
duilib 的IE浏览器控件去边框和去滚动栏的代码
查看>>
.NET平台微服务项目汇集
查看>>
线段树
查看>>
[CSS] Build a Fluid Loading Animation in CSS
查看>>
UWP开发入门(八)——聊天窗口和ItemTemplateSelector
查看>>
Java线程之Callable和Future
查看>>
多线程的实现及常用方法_DAY23
查看>>
在访问RESTful接口时出现:Could not write content: No serializer found for class的问题解决小技巧收集...
查看>>
linux下vim命令详解
查看>>
[AngularFire] Firebase OAuth Login With Custom Firestore User Data
查看>>
c++11 nullptr
查看>>
SpringMVC系列(二): SpringMVC各个注解的使用
查看>>