基礎——堆和棧的區別
堆和棧的區別在許多的面試中都有提及,他們的區別在計算機程式設計中也是屬於非常基礎的部分,不過我之前一直沒去了解……
不過在瞭解之後也很簡單的。
首先我們要知道程式所佔的記憶體一共分為5大塊,分別是
1、堆
2、棧
3、初始化區
4、未初始化區
5、程式碼區
堆——由程式設計師分配記憶體釋放的,比如new指令、alloc指令和malloc指令
棧——由編譯器自己分配釋放的,用來存放一些引數值,區域性變數的值之類的,就是除了堆和static和const以外的就都是棧了,一般編譯器的棧大小是已經固定好的
借鑑一個程式程式碼的例子:
這是一個前輩寫的,非常詳細
//main.cpp
int a = 0; 全域性初始化區
char *p1; 全域性未初始化區
main()
{
int b; 棧
char s[] = "abc"; 棧
char *p2; 棧
char *p3 = "123456"; 123456/0在常量區,p3在棧上。
static int c =0; 全域性(靜態)初始化區
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得來得10和20位元組的區域就在堆區。
strcpy(p1, "123456"); 123456/0放在常量區,編譯器可能會將它與p3所指向的"123456"
優化成一個地方。
}
a在初始化區
p1在未初始化區
b這裡雖然沒給他值,但是他還是佔有一個隨機值,位元組為4,放在了棧中
s陣列為字元陣列,已初始化,大小為4,放在棧中
p2指標,32位計中固定佔了4位元組,棧中
p3指標,4位元組,棧中,指向常量區中的123456/0的首位元組
c 初始化區
之後是為p1、p2開闢了10和20位元組的堆區域
strcpy是為p1賦值,如果進行了優化,就指向了常量區,否則就把值放入堆中
堆和棧的比較:
1、開闢方式
棧是在你定義之後直接由模擬器給你開闢的空間
例如p2,p3
堆是由程式設計師申請的大小,如malloc(10)就是申請10位元組大小的空間
直接用new的話就是申請物件所佔的位元組空間
2、大小
棧是固定的常量,由模擬器決定
堆的大小為計算機系統中有效的虛擬記憶體容量。所以堆的容量遠遠的大於棧
3、儲存方式
棧由於是編譯器申請的,所以它所開闢的空間都是連續行的,即使在釋放之後也不會產生什麼碎片。
堆得位置都是隨機生成的,所以他比較自由,例如連結串列你是沒法通過簡單的加上所佔位元組得到下一個鏈的位置,同時由於隨機,堆會產生碎片,不過用起來比較方便
4、響應
棧的響應速度快,不過棧所申請的記憶體必須小於剩餘空間,否則會報棧溢位
堆得響應速度偏慢,它在申請的時候會在一個空閒表找到一個堆節點大於所申請的空間,並且把這個節點分配給堆,多於的大小重新放入空閒表中
(PS:作業系統有一個記錄空閒記憶體地址的連結串列)(PPS: 所謂的碎片就是空閒表中太小的空間,在兩塊已經被申請的空間中間並且基本上不會被用到的)
5、效率
效率嘛,不用多想,肯定是棧快
總結
堆和棧各有好壞
棧快但又不靈活而且還小
堆慢但是靈活,可分配記憶體大
在使用上棧比堆簡單,所以若是佔記憶體小且不是特別的扣記憶體的話,不妨用棧的簡單
相關文章
- 堆和棧的區別
- java堆和棧的區別Java
- 堆和棧的概念和區別
- Java中堆和棧的區別Java
- 堆(heap)和棧(stack)的區別
- 堆和棧的解釋和區別
- 堆和棧在物理上的區別
- python堆和棧的區別有哪些Python
- 記憶體分配策略中,堆和棧的區別記憶體
- 關於記憶體中棧和堆的區別記憶體
- 堆和棧的區別(轉過無數次的文章)
- 棧與堆的區別以及增長方向
- C++基礎-1-記憶體管理(全域性區、堆區、棧區)C++記憶體
- C#中堆和堆疊的區別C#
- C語言程式的內在分配:堆和棧以及char a[]和char*的區別C語言
- JAVA堆區棧區方法區Java
- Python中堆、棧、佇列之間的區別Python佇列
- [CLR via C#]4. 型別基礎及型別、物件、棧和堆執行時的相互聯絡C#型別物件
- JAVA的堆和棧(轉)Java
- Java基礎- ==和equals和hashCode的區別Java
- [sass 基礎] .sass 和 .scss 區別CSS
- 基礎才是重中之重~lock和monitor的區別
- JavaScript理解堆和棧JavaScript
- JVM之棧、堆、方法區(三)JVM
- 記憶體四區之程式碼區,全域性區,棧區和堆區記憶體
- Kafka基礎:表和流的區別 - Edward LoveallKafka
- C++基礎(八)struct和class的區別C++Struct
- C#引用型別和值型別在堆、棧中的儲存C#型別
- Vue 基礎自查——watch、computed和methods的區別Vue
- C++中堆和棧的完全解析C++
- 堆和棧在程式中的比較
- Java中棧和堆講解Java
- 如何正確理解棧和堆?
- jQuery基礎與js的區別jQueryJS
- 關於堆區、棧區等五大區的終極分析
- 程式的記憶體分配:棧區(stack)堆區(heap)。。。(轉載)記憶體
- Java基礎-成員變數和區域性變數的區別Java變數
- 簡單資料型別和引用資料型別對應棧和堆示意圖資料型別