<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      內存的分配VS回收&構造函數(shù)VS析構函數(shù)

      之前有一個問題一直困擾著我,就是一個變量出了作用域,我以為這個變量的內存就被回收了,其實不是這樣的,昨天問了一個高手,才豁然開朗,自己在看相關代碼的反匯編代碼,才知道原來真是這樣就。這個問題,我想簡單的說一下內存的分配VS回收&構造函數(shù)VS析構函數(shù)之間的關系。

      我的疑問:為什么p出了作用域,指向p的ptr還能讀到p中arr的內容,難道p出了作用域,還沒有析構?

      下面的內容會解答這個疑問,先說說跟這篇文章有關的內容。

      可能是因為平時習慣的原因,我們在實例化一個對象的時候,往往是一條語句實現(xiàn)兩個功能:1分配內存;2調用構造函數(shù)

      class A
      {
      public:
          A()
          {
              i=0;
              j=0;
          }
      
          ~A(){}
          int i;
          int j;
      };
       
      A a1; 
      A * a2=new A();

      這兩中方式都是一步實現(xiàn)兩個操作,分配內存和調用構造函數(shù),如果A沒寫構造函數(shù),即沒有構造函數(shù)(編譯器也不會自動生成),當然就不需要調用構造函數(shù)。

      其實這兩步是可以分開的,A a1;這句分開不了這兩步,但A * a2=new A();是可以分開,同等的代碼如下:

      void* memory=operator new(sizeof(A));//分配內存

      A* a2=new(memory) A();//在memory上調用A的構造函數(shù)

      回收的時候,我們可以這樣寫:

      delete a2;//這句等同下面兩句

      //a2->~A();

      //operator delete(memory);

      如果A沒有析構函數(shù),當然delete時也不會調用,原因請看我的博客:構造函數(shù)產生的點及原因。

      也就是說A* a=new A();delete a;這兩條語句,執(zhí)行了四個操作:

      分配內存->調用構造函數(shù)->調用析構函數(shù)->回收內存;

      更多關于這四步分開的代碼:

      而我今天要說的是,這四步是完全可以分開的。既然這四步是可以分開的,那么解答上面那個疑問就很簡單了。

      Char* ptr;

      {

            Point p;

            ptr=p;

      }

      P出了作用域,為什么ptr還能讀到他的內容,原因很簡單:因為上面幾行代碼只執(zhí)行了前面三步,最后一步回收內存,還沒有執(zhí)行。出了作用域,就會執(zhí)行析構,沒說要回收內存,棧的內存要在方法返回之前才回收,也就是說一個方法如果大量的分配內存是很容易爆棧,即是你讓棧中的變量出了作用域也沒用,請不要搞混了。棧內存在方法返回的時候才回收,這一點就是爆棧的最重要原因,為什么不是在變量出作用域的時候,調用完析構函數(shù),就回收內存呢?我也不知道為什么?,看方法test11的反匯編代碼,的確是在方法返回的時候才回收內存?

      那個疑問的源碼如下:

      #include "stdafx.h" 
      #include <iostream> 
      using namespace std;
         
      struct Point
      {
          char arr[10];
          Point()
          {
              for(int i=0;i<9;i++)
              {
                  arr[i]='a';
              }
              arr[9]='\0';
          }
          ~Point(){}
          operator char*()
          {
              return arr;
          }
      };
      
      void test11()
      {
          char* ptr;
          {
              Point p;
              ptr=p;
          }
          cout<<ptr<<endl;
      }
        
      int _tmain(int argc, _TCHAR* argv[])
      {    
          {  
               test11(); 
          } 
          system("pause");
          return 0; 
      }

      test11的反匯編代碼如下:

      void test11()
      {
      010431F0  push        ebp  //ebp表示棧頂指針
      010431F1  mov         ebp,esp  //esp表示棧當前指針
      009C31F3  push        0FFFFFFFFh  
      009C31F5  push        offset __ehhandler$?test11@@YAXXZ (9CA3C8h)  
      009C31FA  mov         eax,dword ptr fs:[00000000h]  
      009C3200  push        eax  
      009C3201  sub         esp,0E4h  
      009C3207  push        ebx  
      009C3208  push        esi  
      009C3209  push        edi  
      009C320A  lea         edi,[ebp-0F0h]  
      B::`scalar deleting destructor':
      009C3210  mov         ecx,39h  
      009C3215  mov         eax,0CCCCCCCCh  
      009C321A  rep stos    dword ptr es:[edi]  
      009C321C  mov         eax,dword ptr [___security_cookie (9CF070h)]  
      009C3221  xor         eax,ebp  
      009C3223  mov         dword ptr [ebp-10h],eax  
      009C3226  push        eax  
      009C3227  lea         eax,[ebp-0Ch]  
      009C322A  mov         dword ptr fs:[00000000h],eax  
          char* ptr;
          {
              Point p;
      009C3230  lea         ecx,[p]  
      009C3233  call        Point::Point (9C1541h)  
      009C3238  mov         dword ptr [ebp-4],0  
              ptr=p;
      009C323F  lea         ecx,[p]  
      009C3242  call        A::~A (9C1546h)  
      009C3247  mov         dword ptr [ebp-18h],eax  
          }
      009C324A  mov         dword ptr [ebp-4],0FFFFFFFFh  
      009C3251  lea         ecx,[p]  
      009C3254  call        A::`scalar deleting destructor' (9C154Bh)  
          cout<<ptr<<endl;
      009C3259  mov         esi,esp  
      009C325B  mov         eax,dword ptr [__imp_std::endl (9D039Ch)]  
      009C3260  push        eax  
      009C3261  mov         ecx,dword ptr [ebp-18h]  
      009C3264  push        ecx  
      009C3265  mov         edx,dword ptr [__imp_std::cout (9D03A0h)]  
      009C326B  push        edx  
      009C326C  call        std::operator<<<std::char_traits<char> > (9C132Fh)  
      009C3271  add         esp,8  
      009C3274  mov         ecx,eax  
      009C3276  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (9D0390h)]  
      009C327C  cmp         esi,esp  
      009C327E  call        @ILT+960(__RTC_CheckEsp) (9C13C5h)  
      }
      009C3283  push        edx  
      009C3284  mov         ecx,ebp  
      009C3286  push        eax  
      009C3287  lea         edx,[ (9C32C0h)]  
      009C328D  call        @ILT+350(@_RTC_CheckStackVars@8) (9C1163h)  
      009C3292  pop         eax  //pop開始出棧  注意;這里才開始回收內存 
      09C3293   pop         edx  
      009C3294  mov         ecx,dword ptr [ebp-0Ch]  
      009C3297  mov         dword ptr fs:[0],ecx  
      009C329E  pop         ecx  
      009C329F  pop         edi  
      009C32A0  pop         esi  
      009C32A1  pop         ebx  
      009C32A2  mov         ecx,dword ptr [ebp-10h]  
      009C32A5  xor         ecx,ebp  
      009C32A7  call        @ILT+65(@__security_check_cookie@4) (9C1046h)  
      009C32AC  add         esp,0F0h  
      009C32B2  cmp         ebp,esp  
      009C32B4  call        @ILT+960(__RTC_CheckEsp) (9C13C5h)  
      009C32B9  mov         esp,ebp  //棧頂指針和棧當前指針指向同一個地址,即棧的長度就是一個指針的長度
      009C32BB  pop         ebp  //棧頂指針彈出,現(xiàn)在棧空了
      009C32BC  ret  

      我有這個疑問的原因就是:我以為在出作用域的時候不僅調用析構函數(shù),還要回收內存,其實只是調用析構函數(shù),內存在方法返回的時候才回收。

      posted @ 2013-11-09 09:43  古文觀芷  閱讀(2875)  評論(10)    收藏  舉報
      主站蜘蛛池模板: 国产伦精品一区二区三区妓女 | 美女爽到高潮嗷嗷嗷叫免费网站| 99国产精品白浆在线观看免费| 日韩一区二区三区一级片| 国产精品推荐手机在线| 仪征市| 日韩中文字幕亚洲精品| 亚洲不卡一区三区三区四| 97久久久亚洲综合久久| 国产精品美女久久久久久麻豆| 国产成人理论在线视频观看| 伦伦影院精品一区| √天堂中文www官网在线| 久久亚洲精品11p| 91中文字幕一区在线| 国产欧美久久一区二区三区| 被黑人巨大一区二区三区| 日本高清不卡一区二区三| 蜜臀98精品国产免费观看| 欲色欲色天天天www| 亚洲av熟女国产一二三| 午夜在线不卡| 日韩精品亚洲专在线电影| 综合激情网一区二区三区| 亚洲国产成人精品无码区蜜柚| 亚洲国产日韩一区三区| 国产91麻豆视频免费看| 亚洲情综合五月天| 熟妇的奶头又大又长奶水视频| 国产精品黄色片在线观看| 免费黄色大全一区二区三区| 免费视频一区二区三区亚洲激情 | 国产精品天干天干综合网| 国产精品美女www爽爽爽视频| 高清无码爆乳潮喷在线观看| 亚洲人成网站999久久久综合| 久久精品国产亚洲av亚| 国产色无码专区在线观看| 亚洲日韩一区二区| www国产成人免费观看视频| 天堂V亚洲国产V第一次|