程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 關於new和delete 一些不得不說的事(1)

關於new和delete 一些不得不說的事(1)

編輯:C++入門知識

當你寫下new和delete的時候,到底發生了什麼事呢,讓我們來做個試驗看看。

寫一段小代碼:

  1. class a  
  2. {  
  3. public:  
  4.  a()  
  5.  {  
  6.   foo();  
  7.  }  
  8.  int foo()  
  9.  {  
  10.   return 0;  
  11.  }  
  12.  
  13.  ~a()  
  14.  {  
  15.   bar();  
  16.  }  
  17.  
  18.  int bar()  
  19.  {  
  20.   return 1;  
  21.  }  
  22. };  
  23.  
  24. int _tmain(int argc, _TCHAR* argv[])  
  25. {  
  26.  a* tmp = new a();  
  27.  delete tmp;  
  28.  return 0;  
  29. }  

在main函數的第一句下斷點,調試,然後開匯編窗口輸出結果:

  1. int _tmain(int argc, _TCHAR* argv[])  
  2. {  
  3. 004113F0  push        ebp    
  4. 004113F1  mov         ebp,esp   
  5. 004113F3  push        0FFFFFFFFh   
  6. 004113F5  push        offset __ehhandler$_wmain (41478Eh)   
  7. 004113FA  mov         eax,dword ptr fs:[00000000h]   
  8. 00411400  push        eax    
  9. 00411401  sub         esp,100h   
  10. 00411407  push        ebx    
  11. 00411408  push        esi    
  12. 00411409  push        edi    
  13. 0041140A  lea         edi,[ebp-10Ch]   
  14. 00411410  mov         ecx,40h   
  15. 00411415  mov         eax,0CCCCCCCCh   
  16. 0041141A  rep stos    dword ptr es:[edi]   
  17. 0041141C  mov         eax,dword ptr [___security_cookie (418000h)]   
  18. 00411421  xor         eax,ebp   
  19. 00411423  push        eax    
  20. 00411424  lea         eax,[ebp-0Ch]   
  21. 00411427  mov         dword ptr fs:[00000000h],eax   
  22.  /*a* tmp = new a();*/ 
  23. 0041142D  push        1      
  24. 0041142F  call        operator new (4111A4h)   
  25. 00411434  add         esp,4   
  26. 00411437  mov         dword ptr [ebp-0F8h],eax   
  27. 0041143D  mov         dword ptr [ebp-4],0   
  28. 00411444  cmp         dword ptr [ebp-0F8h],0   
  29. 0041144B  je          wmain+70h (411460h)   
  30. 0041144D  mov         ecx,dword ptr [ebp-0F8h]   
  31. 00411453  call        a::a (41101Eh)   
  32. 00411458  mov         dword ptr [ebp-10Ch],eax   
  33. 0041145E  jmp         wmain+7Ah (41146Ah)   
  34. 00411460  mov         dword ptr [ebp-10Ch],0   
  35. 0041146A  mov         eax,dword ptr [ebp-10Ch]   
  36. 00411470  mov         dword ptr [ebp-104h],eax   
  37. 00411476  mov         dword ptr [ebp-4],0FFFFFFFFh   
  38. 0041147D  mov         ecx,dword ptr [ebp-104h]   
  39. 00411483  mov         dword ptr [ebp-14h],ecx   
  40.  /*delete tmp;*/ 
  41. 00411486  mov         eax,dword ptr [ebp-14h]   
  42. 00411489  mov         dword ptr [ebp-0E0h],eax   
  43. 0041148F  mov         ecx,dword ptr [ebp-0E0h]   
  44. 00411495  mov         dword ptr [ebp-0ECh],ecx   
  45. 0041149B  cmp         dword ptr [ebp-0ECh],0   
  46. 004114A2  je          wmain+0C9h (4114B9h)   
  47. 004114A4  push        1      
  48. 004114A6  mov         ecx,dword ptr [ebp-0ECh]   
  49. 004114AC  call        a::`scalar deleting destructor' (41117Ch)   
  50. 004114B1  mov         dword ptr [ebp-10Ch],eax   
  51. 004114B7  jmp         wmain+0D3h (4114C3h)   
  52. 004114B9  mov         dword ptr [ebp-10Ch],0   
  53.  /*return 0;*/ 
  54. 004114C3  xor         eax,eax   
  55. }  
  56. 004114C5  mov         ecx,dword ptr [ebp-0Ch]   
  57. 004114C8  mov         dword ptr fs:[0],ecx   
  58. 004114CF  pop         ecx    
  59. 004114D0  pop         edi    
  60. 004114D1  pop         esi    
  61. 004114D2  pop         ebx    
  62. 004114D3  add         esp,10Ch   
  63. 004114D9  cmp         ebp,esp   
  64. 004114DB  call        @ILT+345(__RTC_CheckEsp) (41115Eh)   
  65. 004114E0  mov         esp,ebp   
  66. 004114E2  pop         ebp    
  67. 004114E3  ret     

前面一片調整stack,插入安全代碼,設置異常處理等的操作不是今天我們要說的重點,直接跳到a* tmp = new a();這一句產生的反匯編:

  1. 0041142F call operator new (4111A4h) 

我們很明確的看到調用了一個函數operator new。繼續跟進operator new看到底做了什麼事情:

  1. void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)  
  2.         {       // try to allocate size bytes  
  3.         void *p;  
  4.         while ((p = malloc(size)) == 0)  
  5.                 if (_callnewh(size) == 0)  
  6.                 {       // report no memory  
  7.                 static const std::bad_alloc nomem;  
  8.                 _RAISE(nomem);  
  9.                 }  
  10.  
  11.         return (p);  
  12.         }  

很意外吧,其實operator new函數就做了那麼一件事情:調用malloc函數分配內存。有沒有負責調用構造函數?這個真沒有。。。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved