网站首页 > 物联资讯 > 技术分享

关于delete和delete[]

2016-09-28 00:00:00 广州睿丰德信息科技有限公司 阅读
睿丰德科技 专注RFID识别技术和条码识别技术与管理软件的集成项目。质量追溯系统、MES系统、金蝶与条码系统对接、用友与条码系统对接

[精彩] 求问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[]的原因。

RFID管理系统集成商 RFID中间件 条码系统中间层 物联网软件集成