1. 程式人生 > >Stack的三種含義(轉載)

Stack的三種含義(轉載)

理解這個概念,對於理解程式的執行至關重要。容易混淆的是,這個詞其實有三種含義,適用於不同的場合,必須加以區分。

含義一:資料結構

stack的第一種含義是一組資料的存放方式,特點為LIFO,即後進先出(Last in, first out)。

資料結構stack

在這種資料結構中,資料像積木那樣一層層堆起來,後面加入的資料就放在最上層。使用的時候,最上層的資料第一個被用掉,這就叫做"後進先出"。

與這種結構配套的,是一些特定的方法,主要為下面這些。

  • push:在最頂層加入資料。
  • pop:返回並移除最頂層的資料。
  • top:返回最頂層資料的值,但不移除它。
  • isempty:返回一個布林值,表示當前stack是否為空棧。

含義二:程式碼執行方式

stack的第二種含義是"呼叫棧"(call stack),表示函式或子例程像堆積木一樣存放,以實現層層呼叫。

下面以一段Java程式碼為例(來源)。

 class Student{     int age;                   String name;            public Student(int Age, String Name)     {         this.age = Age;         setName(Name);     }     public void setName(String Name)     {         this.name =
Name; } } public class Main{ public static void main(String[] args) { Student s; s = new Student(23,"Jonh"); } }

上面這段程式碼執行的時候,首先呼叫main方法,裡面需要生成一個Student的例項,於是又呼叫Student建構函式。在建構函式中,又呼叫到setName方法。

呼叫棧

這三次呼叫像積木一樣堆起來,就叫做"呼叫棧"。程式執行的時候,總是先完成最上層的呼叫,然後將它的值返回到下一層呼叫,直至完成整個呼叫棧,返回最後的結果。

含義三:記憶體區域

stack的第三種含義是存放資料的一種記憶體區域。程式執行的時候,需要記憶體空間存放資料。一般來說,系統會劃分出兩種不同的記憶體空間:一種叫做stack(棧),另一種叫做heap(堆)。

記憶體區域stack

它們的主要區別是:stack是有結構的,每個區塊按照一定次序存放,可以明確知道每個區塊的大小;heap是沒有結構的,資料可以任意存放。因此,stack的定址速度要快於heap。

記憶體區域heap

其他的區別還有,一般來說,每個執行緒分配一個stack,每個程序分配一個heap,也就是說,stack是執行緒獨佔的,heap是執行緒共用的。此外,stack建立的時候,大小是確定的,資料超過這個大小,就發生stack overflow錯誤,而heap的大小是不確定的,需要的話可以不斷增加。

根據上面這些區別,資料存放的規則是:只要是區域性的、佔用空間確定的資料,一般都存放在stack裡面,否則就放在heap裡面。請看下面這段程式碼(來源)。

 public void Method1() {     int i=4;      int y=2;      class1 cls1 = new class1(); }  

上面程式碼的Method1方法,共包含了三個變數:i, y 和 cls1。其中,i和y的值是整數,記憶體佔用空間是確定的,而且是區域性變數,只用在Method1區塊之內,不會用於區塊之外。cls1也是區域性變數,但是型別為指標變數,指向一個物件的例項。指標變數佔用的大小是確定的,但是物件例項以目前的資訊無法確知所佔用的記憶體空間大小。

這三個變數和一個物件例項在記憶體中的存放方式如下。

記憶體空間stack例項

從上圖可以看到,i、y和cls1都存放在stack,因為它們佔用記憶體空間都是確定的,而且本身也屬於區域性變數。但是,cls1指向的物件例項存放在heap,因為它的大小不確定。作為一條規則可以記住,所有的物件都存放在heap。

接下來的問題是,當Method1方法執行結束,會發生什麼事?

回答是整個stack被清空,i、y和cls1這三個變數消失,因為它們是區域性變數,區塊一旦執行結束,就沒必要再存在了。而heap之中的那個物件例項繼續存在,直到系統的垃圾清理機制(garbage collector)將這塊記憶體回收。因此,一般來說,記憶體洩漏都發生在heap,即某些記憶體空間不再被使用了,卻因為種種原因,沒有被系統回收。

posted on 2013-12-07 11:41 Richard Wei 閱讀(1340) 評論(0)  編輯 收藏 引用 所屬分類: C++