(轉)C++棧和堆原理介紹

(轉自:http://blog.pfan.cn/maliang1225/27508.html

C++應用中內存分爲2部分,一部分是棧(stack,也稱堆棧),另一部分是堆(heap)。

          棧: 可以把棧看成是一疊卡片,最上面的卡片表示程序的當前作用域,這往往就是當前正在執行的函數。當前函數中聲明的所有變量都置於棧頂幀中,即佔用棧頂幀的內存,這就相當於一疊卡片中最上面的一張卡片。如果當前函數調用了另一個函數,舉例來說,一開始一疊卡片位於最底的卡片是main()函數,main()函數調用了foo()函數,則相當於在這一疊卡片上加了另一張卡片,這樣foo()函數就有了自己的棧幀(就是指一塊內存空間)以供使用。從main()傳遞到foo()的所有參數都會從main()棧幀複製到foo()棧幀中。 然後foo()函數又調用了bar()函數,則在這一疊卡片上又加了一張卡片,這樣bar()就有了自己的棧幀(stack frame)以供使用,從foo()傳遞到bar()的參數就會從foo()棧幀複製到bar()棧幀中。 圖片如下: foo()函數聲明瞭一個整數值。


             棧幀很有意義,因爲棧幀可以爲每個函數提供一個獨立的內存工作區。如果一個變量是在foo()棧幀中聲明的,那麼調用bar()函數不會對它帶來改變,除非你專門要求修改這個變量。另外,foo()函數運行結束時,棧幀既消失,該函數中聲明的所有變量就不會再佔用內存了。。

             堆:堆是一段完全獨立於當前函數或棧幀的內存區。如果一個函數中聲明瞭一些變量,而且希望當這個函數結束時其中聲明的變量依然存在,就可以將這些變量置於堆中。堆與棧相比,沒有那麼清晰的結構性。可以把堆看作是一“堆”小玩藝。程序可以在任何時刻向這個“堆”添加新的東西或者修改“堆”中已經有的東西。

            用棧和堆來分析動態分配數組的原理: 根據棧的工作原理,編譯器在編譯時就必然能夠確定每個棧幀有多大。 由於棧幀大小是預定的,因此無法聲明一個大小可變的數組。 如: 以下代碼就無法通過編譯,因爲arraySize是變量,而不是常量。

             int arraySize = 8;

             int myVaraibleSizedArray( arraySize );           // 不能通過編譯

由於整個數組都要放在棧上,編譯器需要準確地知道數組的大小(根據棧的工作原理,編譯器在編譯時必須要確定每個棧幀有多大。)所以不充許用變量來指定數組大小,如果通過使用動態內存(dynamic memory),把數組放在堆中(而不是棧中),就可以在運行時才指定數組的大小。

要動態分配一個數組,首先需要聲明一個指針(pointer):

           int * myVariableSizedArray;

          myVariableSizeArray = new int[arraySize];        // 在堆中分配數組空間

這就會根據arraySize變量的大小來分配相應的內存。可以看到,指針變量任然位於棧中,而指針指向的數組則位於堆中。。

然而由於堆中變量佔用的內存空間不會因爲程序或函數結束而釋放掉(在棧中變量則會因爲程序或函數結束而釋放內存),因此就需要人工來釋放掉堆中的內存。用delete命令來釋放內存.

          delete [] myVariableSizeArray;



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章