<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    關于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中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全