面試官問到堆和棧的區別該怎麼回答?一文搞懂堆和棧的區別

編程經常需要操作的內存

在這裏插入圖片描述

  • 棧區(stack):由編譯器自動分配和釋放,存放函數的參數值、局部變量的值等。其操作方式類似於數據結構中的棧。
  • 堆區(heap):一般由程序員分配和釋放,若程序員不釋放,程序結束時可能由操作系統回收。它與數據機構中的堆是兩回事,分配方式類似於鏈表。
  • 全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一起的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另外一塊區域。程序結束後由系統釋放。
  • 文字常量區:常量字符串就是放在這裏。程序結束後由系統釋放。
  • 程序代碼區:存放函數體的二進制代碼

堆和棧的區別

1申請方式

  • 棧:由系統自動分配。例如在聲明函數的一個局部變量int b,系統自動在棧中爲b開闢空間。
  • 堆:需要程序員自己申請,並指明大小,在C中用malloc函數;在C++中用new運算符。

2申請後系統的響應

  • 棧:只要棧的剩餘空間大於所申請的空間系統將爲程序提供內存,否則將報異常提示棧溢出。
  • 堆:操作系統有一個記錄空間內存地址的鏈表,當系統收到程序的申請時,會遍歷鏈表,尋找第一個空間大於所申請空間的堆節點,然後將節點從內存空閒節點鏈表中刪除,並將該節點的空間分配給程序。對於大多數操作系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內存空間。另外,由於找到的對節點的大小不一定正好等於申請的大小,系統會自動地將多餘的那部分重新放入到鏈表中。

3申請大小的限制

  • 棧:在Windows下,棧是向低地址拓展的數據結構,是一塊連續的內存的區域。站定地址和棧的大小是系統預先規定好的,如果申請的內存空間超過棧的剩餘空間,將提示棧溢出
  • 堆:堆是向高地址拓展的內存結構,是不連續的內存區域。是系統用鏈表存儲空閒內存地址的,不連續

4申請效率的比較

  • 棧:由系統自動分配,速度較快。但程序員無法控制。
  • 堆:由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來方便。
    拓展:在Windows操作系統中,最好的方式使用VirtualAlloc分配內存。不是在堆,不是在棧,而是在內存空間中保留一塊內存,雖然用起來不方便,但是速度快,也很靈活。

5堆和棧的存儲內容

  • 棧:在函數調用時,第一個進棧的是主函數的中的下一條指令(函數調用的下一個可執行語句)的地址,然後是函數的各個參數。在C編譯器中,參數是由右往左入棧的,然後是函數的局部變量。靜態變量不入棧。
  • 堆:一般是在堆的頭部用一個字節存放堆的大小。堆中的具體內容由程序員安排。
    數據結構方面的堆和棧與上邊敘述不同。這裏的堆是指優先隊列的一種數據結構,第一個元素有最高的優先權;棧實際就是滿足先進後出的性質的數學或數據結構。

總結:
(1)heap是堆,stack是棧;
(2)stack的空間由操作系統自動分配/釋放,heap上的空間手動分配/釋放;
(3)stack空間有限,heap是很大的自由內存區;
(4)C中的malloc函數分配的內存空間即在堆上,C++中對應的是new操作符。
程序在編譯對變量和函數分配內存都在棧上進行,且內存運行過程中函數調用時參數的傳遞在棧上進行。

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