关于delete和delete[]

简介: [精彩] 求问delete和delete[] 的区别??http://www.chinaunix.net/jh/23/311058.htmlC++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。

[精彩] 求问delete和delete[] 的区别??
http://www.chinaunix.net/jh/23/311058.html


C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。 

楼主的这个问题提得很好。很多人注意到了这个问题,但是却不清楚为什么要这样做,不这样做行不行。 

关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。 

对于 (1),上面提供的程序已经证明了 delete[] 和 delete 是等同的。但是对于 (2),情况就发生了变化。请看下面的程序。 
#include <iostream>;

using namespace std;



class T {

public:

  T() { cout << "constructor" << endl; }

  ~T() { cout << "destructor" << endl; }

};



int main()

{

  const int NUM = 3;



  T* p1 = new T[NUM];

  cout << hex << p1 << endl;

  //  delete[] p1;

  delete p1;



  T* p2 = new T[NUM];

  cout << p2 << endl;

  delete[] p2;}


大家可以自己运行这个程序,看一看 delete p1 和 delete[] p1 的不同结果,我就不在这里贴运行结果了。 

从运行结果中我们可以看出,delete p1 在回收空间的过程中,只有 p1[0] 这个对象调用了析构函数,其它对象如 p1[1]、p1[2] 等都没有调用自身的析构函数,这就是问题的症结所在。如果用 delete[],则在回收空间之前所有对象都会首先调用自己的析构函数。 

基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[] 回收空间。 

所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。






 [C++] 关于delete和delete[]  
From:     
http://blog.csdn.net/wwwsq/article/details/5310912  


首先贴一段MFC的源代码:

 

void __cdecl operator delete(void* p)
{
        free(p);
}

 

void __cdecl operator delete[](void* p)
{
    ::operator delete(p);
}

 

 

然后贴一点汇编:

 

  1.     char* p = new char[100];  
  2. 00402CE1  push        64h    
  3. 00402CE3  call        operator new[] (4051C6h)   
  4. 00402CE8  add         esp,4   
  5. 00402CEB  mov         dword ptr [ebp-7Ch],eax   
  6. 00402CEE  mov         eax,dword ptr [ebp-7Ch]   
  7. 00402CF1  mov         dword ptr [p],eax   
  8.     delete p;  
  9. 00402CF4  mov         eax,dword ptr [p]   
  10. 00402CF7  mov         dword ptr [ebp-78h],eax   
  11. 00402CFA  mov         ecx,dword ptr [ebp-78h]   
  12. 00402CFD  push        ecx    
  13. 00402CFE  call        operator delete (4051C1h)   
  14. 00402D03  add         esp,4   
  15.     delete [] p;  
  16. 00402D06  mov         eax,dword ptr [p]   
  17. 00402D09  mov         dword ptr [ebp-74h],eax   
  18. 00402D0C  mov         ecx,dword ptr [ebp-74h]   
  19. 00402D0F  push        ecx    
  20. 00402D10  call        operator delete[] (4051CBh)   
  21. 00402D15  add         esp,4   

分析:

其中的call operator delete (4051C1h) 就是去调用MFC的void __cdecl operator delete(void* p)

其中的call operator delete[] (4051CBh) 就是去调用MFC的void __cdecl operator delete[](void* p)

所以在这种情下,两者是完全等效的。

 

 

  1.     A* a = new A[100];  
  2. 00402D18  push        194h   
  3. 00402D1D  call        operator new[] (4051C6h)   
  4. 00402D22  add         esp,4   
  5. 00402D25  mov         dword ptr [ebp-6Ch],eax   
  6. 00402D28  mov         dword ptr [ebp-4],0   
  7. 00402D2F  cmp         dword ptr [ebp-6Ch],0   
  8. 00402D33  je          CTestMFCDlg::OnBnClickedButton9+0A3h (402D63h)   
  9. 00402D35  mov         eax,dword ptr [ebp-6Ch]   
  10. 00402D38  mov         dword ptr [eax],64h   
  11. 00402D3E  push        offset A::~A (402E00h)   
  12. 00402D43  push        offset A::A (402DE0h)   
  13. 00402D48  push        64h    
  14. 00402D4A  push        4      
  15. 00402D4C  mov         ecx,dword ptr [ebp-6Ch]   
  16. 00402D4F  add         ecx,4   
  17. 00402D52  push        ecx    
  18. 00402D53  call        `eh vector constructor iterator' (443BA8h)   
  19. 00402D58  mov         edx,dword ptr [ebp-6Ch]   
  20. 00402D5B  add         edx,4   
  21. 00402D5E  mov         dword ptr [ebp-80h],edx   
  22. 00402D61  jmp         CTestMFCDlg::OnBnClickedButton9+0AAh (402D6Ah)   
  23. 00402D63  mov         dword ptr [ebp-80h],0   
  24. 00402D6A  mov         eax,dword ptr [ebp-80h]   
  25. 00402D6D  mov         dword ptr [ebp-70h],eax   
  26. 00402D70  mov         dword ptr [ebp-4],0FFFFFFFFh   
  27. 00402D77  mov         ecx,dword ptr [ebp-70h]   
  28. 00402D7A  mov         dword ptr [a],ecx   
  29.     delete a;  
  30. 00402D7D  mov         eax,dword ptr [a]   
  31. 00402D80  mov         dword ptr [ebp-64h],eax   
  32. 00402D83  mov         ecx,dword ptr [ebp-64h]   
  33. 00402D86  mov         dword ptr [ebp-68h],ecx   
  34. 00402D89  cmp         dword ptr [ebp-68h],0   
  35. 00402D8D  je          CTestMFCDlg::OnBnClickedButton9+0DEh (402D9Eh)   
  36. 00402D8F  push        1      
  37. 00402D91  mov         ecx,dword ptr [ebp-68h]   
  38. 00402D94  call        A::`scalar deleting destructor' (402EA0h)   
  39. 00402D99  mov         dword ptr [ebp-80h],eax   
  40. 00402D9C  jmp         CTestMFCDlg::OnBnClickedButton9+0E5h (402DA5h)   
  41. 00402D9E  mov         dword ptr [ebp-80h],0   
  42.     delete [] a;  
  43. 00402DA5  mov         eax,dword ptr [a]   
  44. 00402DA8  mov         dword ptr [ebp-5Ch],eax   
  45. 00402DAB  mov         ecx,dword ptr [ebp-5Ch]   
  46. 00402DAE  mov         dword ptr [ebp-60h],ecx   
  47. 00402DB1  cmp         dword ptr [ebp-60h],0   
  48. 00402DB5  je          CTestMFCDlg::OnBnClickedButton9+106h (402DC6h)   
  49. 00402DB7  push        3      
  50. 00402DB9  mov         ecx,dword ptr [ebp-60h]   
  51. 00402DBC  call        A::`vector deleting destructor' (402E20h)   
  52. 00402DC1  mov         dword ptr [ebp-80h],eax   
  53. 00402DC4  jmp         CTestMFCDlg::OnBnClickedButton9+10Dh (402DCDh)   
  54. 00402DC6  mov         dword ptr [ebp-80h],0   

分析:

其中的call  A::`scalar deleting destructor' (402EA0h) 会call A::~A (402E00h) 然后call operator delete (4051C1h)

其中的call  A::`vector deleting destructor' (402E20h)会循环的为每个对象call  `eh vector destructor iterator' (443C7Dh) 循环结束之后call operator delete[] (4051CBh)

 

 

结论:

1,对于char这样的基础数据类型,delete和delete[]是等价的。

2,对于class A这样带析构函数的类型,delete和delete[]是不同的。

3,如果只有一个对象,那么对象数组在逻辑上可以蜕化成一个对象,但是那样会多一些步骤,性能会稍差一些。这大概是C++需要同时保留delete和delete[]的原因。

目录
相关文章
|
数据可视化 Python
【100天精通Python】Day62:Python可视化_Matplotlib绘图基础,绘制折线图、散点图、柱状图、直方图和饼图,以及自定义图标外观和功能,示例+代码
【100天精通Python】Day62:Python可视化_Matplotlib绘图基础,绘制折线图、散点图、柱状图、直方图和饼图,以及自定义图标外观和功能,示例+代码
527 0
|
8月前
|
JSON API 数据格式
京东商品SKU价格接口(Jd.item_get)丨京东API接口指南
京东商品SKU价格接口(Jd.item_get)是京东开放平台提供的API,用于获取商品详细信息及价格。开发者需先注册账号、申请权限并获取密钥,随后通过HTTP请求调用API,传入商品ID等参数,返回JSON格式的商品信息,包括价格、原价等。接口支持GET/POST方式,适用于Python等语言的开发环境。
1081 11
|
7月前
|
存储 关系型数据库 分布式数据库
PolarDB开源数据库进阶课16 接入PostGIS全功能及应用举例
本文介绍了如何在PolarDB数据库中接入PostGIS插件全功能,实现地理空间数据处理。此外,文章还提供了使用PostGIS生成泰森多边形(Voronoi diagram)的具体示例,帮助用户理解其应用场景及操作方法。
329 1
|
10月前
|
网络协议 安全 算法
OSPFv3新特性介绍
OSPFv3新特性介绍
186 4
|
10月前
|
缓存 算法 Swift
Swift 应用性能优化的重要性及基本原则,包括理解性能瓶颈、针对性优化和平衡性能与代码质量
本文深入探讨了 Swift 应用性能优化的重要性及基本原则,包括理解性能瓶颈、针对性优化和平衡性能与代码质量。具体介绍了优化数据结构、减少对象创建、合理使用缓存、优化算法和内存管理等技巧,并通过实际案例展示了如何有效提升应用性能和用户体验。
220 3
|
安全 Java
Java生产者和消费者模型的5种实现方式
生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。
Java生产者和消费者模型的5种实现方式
|
人工智能 算法 安全
Robot OS系统架构设计
目前移动机器人已得到了大范围应用,无论是在大型商场还是银行都可以看到移动机器人身影。移动机器人主要是移动加决策,移动方式主要以轮式和足式,在商场见到的主要以轮式拟人的形态出现,足式的主要以动物形象为主,前段时间还看到了上海一个小区,机器人上绑着喇叭在小区跑,提示人们注意做好个人防范等。
543 0
|
存储 缓存 安全
微软KV Store Faster如何巧妙实现1.6亿ops | 前沿
微软18年在sigmod上发表了论文Faster: A Concurrent Key-Value Store with In-Place Updates,介绍了一款支持高并发的kv store,在单台机器上可实现1.6亿ops的高吞吐,远胜于其它纯内存数据结构的性能。亮点在于1.6亿的高吞吐,并且支持超出内存大小的数据量,实现方式比较新颖,虽然faster在工程上会有比较多的限制,比较难产品化,但是实现对于优化kv引擎的方向有一定的启发意义,值得学习一下
2019 1
微软KV Store Faster如何巧妙实现1.6亿ops | 前沿
|
JavaScript 前端开发 API
videojs 使用手册
因为最近做了一个关于直播与录播的项目,需要用到播放器,常用的 video 标签无法满足兼容性和可配置性,为了降低编写难度,使用了 videojs 这个库来辅助开发,这里记录一下,方便之后使用回忆。
1520 0
|
Hbase 分布式数据库 存储
深度 | 数据人看Feed流——架构实践
我们在数据存储产品的功能、性能、可用性上的一些理解,希望对真实落地一个Feed流架构可以有一些帮助,以及一起探讨Feed流的未来以及数据产品如何帮助Feed流进一步迭代。
3045 0