2011-06-16 66 views
2

在C++中,如果我們在一個函數內部聲明一個堆棧變量,它會在函數結尾自動刪除還是在程序執行結束時被刪除?在C++中刪除堆棧變量

此外,這個問題的答案是相同的C語言?

回答

6

堆棧聲明的變量,析構函數被調用並且內存回收,因爲它超出了範圍。

請注意,如果變量是在內部塊中聲明的,如if語句或循環,這並不意味着函數結束。

int main(int argc, char **argv) 
{ 
    int a = 3; 

    if (argc > 1) 
    { 
     int b = 5; 
     ++b; 
    } // b is destructed here 

    // a is destructed here 
    // argv and argc are destructed here (or with a) 
} 

編輯:良好有人提出的事實,也無所謂的範圍是如何退出。所以...

#include <vector> 
# include <exception> 

int main(int argc, char **argv) 
{ 
    std::vector<int> myVector(10); 

    try 
    { 
     if (argc) 
     { 
      int a = 10; 
      int b = 12; 
      for (int c = 0; c < b; c++) // lol 
      { 
       int c_squared = c*c; 
       int theEleventhElement = myVector.at(c); 
       // the above will throw std::out_of_range at some point! 
      } 
     } 
    } 
    catch (std::out_of_range &ex) 
    { 
     // do nothing 
    } 
} 

當上述拋出時,堆棧將作爲異常處理的一部分展開。由此,變量將按照以下順序被破壞:

  • c_squared
  • c
  • ba(我想按照這個順序,但如果這是在標準規定的,我不知道)

在這一點上,還有最後一個catch處理程序只有myVector仍然在範圍內。該塊忽略異常,然後main結束 - 在這一點myVector被銷燬。

+1

是的,我知道「破壞」不是一個字。 :-P – 2011-06-16 19:58:34

+0

編輯添加一些關於異常的信息(受lccarrasco的引用標準答案的啓發)。原諒我,如果我的STL知識雖然有點生疏! :-) – 2011-06-16 20:34:11

+0

真棒的答案。真的很清楚額外有趣的情況XD – rrazd 2011-06-16 20:45:01

2

它在超出範圍時被銷燬。 C相同。

+0

由於C沒有「破壞」的概念,變量的內存只是被回收並且不再有效地訪問。 – 2011-06-16 20:33:06

2

自動變量在封閉範圍的末尾自動銷燬。

0

爲了避免與new運營商的模糊性,它可能是更合適地說,變量「彈出」,留下一個函數:看stack-based memory allocation。同樣也適用於C.

0

堆棧變量或多或少是通過遞減堆棧指針來削減堆棧中的幾個字節,它在函數結束時被刪除,但不是簡單地再次移動堆棧指針(用戶的情況 - 定義類型)在C++中,因爲額外的銷燬東西。

在C中,這是向上移動堆棧指針以擺脫所持有的變量的簡單情況。

3

作爲每3.7.2對象具有自動存儲持續時間最後直到它們被創建塊的出口處,有更多的細節在6.6.2

退出時從範圍(然而完成),析構函數(12.4)被調用所有構造的對象與 自動存儲的持續時間(3.7。2)(名稱對象或臨時對象)在該範圍內聲明,其聲明的反向順序。從一個循環中移出一個塊,或者回到一個已初始化的變量 上,自動存儲持續時間涉及銷燬具有自動存儲持續時間的變量, 在範圍內,但是不在傳輸到的點上。