• 关于delete和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[]的原因。

  • 相关阅读:
    android中的webview白屏问题
    7-24分享
    Excel----考勤表制作自动更新日期
    (二十五)微信小程序的登陆 实际逻辑
    微信退款流程
    (二十八)加锁
    (二十七)竞价
    (二十六)拍卖专场相关的接口
    (二十六)微信小程序支付流程
    (二十四)微信小程序支付
  • 原文地址:https://www.cnblogs.com/lidabo/p/3479212.html
Copyright © 2020-2023  润新知