1. 程式人生 > >什麼變數存放在棧和堆

什麼變數存放在棧和堆

內容會持續更新,有錯誤的地方歡迎指正,謝謝!

什麼是棧區,什麼是堆區

棧區(stack):由編譯器自動分配釋放 ,存放函式的引數值、區域性變數的值等,記憶體的分配是連續的,類似於陣列,當我們宣告變數時,編譯器會自動接著當前棧區的結尾來分配記憶體。

堆區(heap):由程式設計師分配釋放, 若程式設計師不釋放,程式結束時由OS回收,記憶體的分配不是連續的,類似於連結串列。

變數存放的位置

C/C++程式佔用的記憶體分為以下幾部分:

  1. 程式程式碼區
  2. 常量區存放常量。程式結束時由OS回收。
  3. 全域性區(靜態區)存放全域性變數和靜態變數。初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。 程式結束時由OS回收。
  4. 堆區存放的變數(用new,malloc,calloc,realloc等分配記憶體函式得到的變數)由程式設計師分配釋放。
  5. 棧區存放的變數(區域性變數、函式引數等)由編譯器自動分配釋放。

記憶體模型:
這裡寫圖片描述

舉例

int a = 0; //全域性初始化區 
char *p1; //全域性未初始化區 
void main() 
{
    int b; //棧 
    char s[] = “abc“;//棧 
    char *p2; //棧 
    char *p3 = “123456“; //123456\0在常量區,p3在棧上;體會與 char s[]="abc"; 的不同
    static int
c =0//全域性初始化區 p2 = (char *)malloc(20); //堆區 strcpy(p1, “123456“); //123456\0在常量區,編譯器可能將它與p3指向的 “123456 “優化成一塊 }

棧區和堆區的關係

1.當一個函式呼叫完返回後它會釋放該函式中所有的棧空間。棧是由編譯器自動管理的,不用你操心。堆是動態分配記憶體的,並且你可以分配使用很大的記憶體,但是用不好會產生記憶體洩漏(比如在for迴圈中忘記釋放申請的記憶體)。
2.棧是機器系統提供的資料結構,特點是快速高效,缺點是有限制,資料不靈活,不會產生記憶體碎片。
3.堆是C/C++函式庫提供的,特點是靈活方便,資料適應面廣泛,但是效率有一定降低,頻繁申請和釋放記憶體會產生記憶體碎片。

總結

使用棧如同在食堂吃飯,只用點菜付錢(申請)、吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作。快捷,但自由度小。

使用堆如同在家吃飯,自己動手做喜歡吃的菜。比較麻煩,但比較符合自己的口味,而且自由度大。