你不知道的堆與棧的區別

2021-09-26 19:30:39 字數 1704 閱讀 8459

1)記憶體分配:

堆:由程式設計師負責申請,並提供申請的大小。在c語言中堆記憶體的分配是用malloc()函式或realloc()來完成的;在c++中用new運算子來分配。堆在使用完成後,也須由程式設計師顯式的釋放。在c語言中釋放的函式為free(),在c++中是用delete操作符負責釋放。若程式設計師忘記釋放,就可能發生記憶體洩漏。程式結束時可能由os**。

棧:由系統自動分配與釋放。例如,宣告在函式中乙個區域性變數 int b;系統自動在棧中為b開闢空間。棧用語存放函式的引數值,區域性變數的值等。

在記憶體資源分配的具體實現上,堆和棧也是有區別的:

堆:堆的分配是通過作業系統的乙個記錄空閒記憶體位址的鍊錶來實現的。當系統收到程式的申請時,會遍歷該鍊錶,尋找第乙個空間大於所申請空間的堆結點,然後將該結點從空閒結點鍊錶中刪除,並將該結點的空間分配給程式,另外,對於大多數系統,會在這塊記憶體空間中的首位址處記錄本次分配的大小,這樣**中的delete語句才能正確的釋放本記憶體空間。另外由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。

棧:每個程序都擁有自己的乙個固定連續的棧空間。在系統分配的時候,只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢位。

2)大小限制:

堆:是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存的空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。

棧:在windows下,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體的區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的,在windows下,棧的大小是固定的(是乙個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示棧溢位。因此,能從棧獲得的空間較小。

windows:

應用棧:預設1m,編譯指令/stack可改設其他值

核心棧:系統根據cpu架構而定,x86系統上為12kb,x64系統上為24kb,安騰系統上為32kb

linux:

核心棧:4k或8k

在thread_info.h:

#ifdef config_4kstacks 

#define thread_size (4096)

#else

#define thread_size (8192)

應用層:10m

3)效率比較:

堆:是由new分配的記憶體,一般速度比較慢,而且容易產生記憶體碎片,不過用起來最方便。值得注意的是,在windows下,最好的方式是用 virtualalloc()分配記憶體,它既不是在堆也不是在棧,而是直接在程序的位址空間中保留一塊記憶體,該方式雖然用起來最不方便,但是速度卻更快,也最靈活。

棧:由系統自動分配,速度較快。但程式設計師是無法控制的。

4)存放內容:

堆:一般是在堆的頭部用乙個位元組存放堆的大小,剩餘部分儲存的內容由由程式設計師根據程式計算的需要決定。

棧:棧是用來記錄程式執行時函式呼叫過程中的活動記錄(棧幀)。在函式呼叫時首先如棧的引數,在大多數的c編譯器中,引數是由右往左入棧,然後是返回位址,緊接著是老ebp暫存器中的值,然後是分配函式中的區域性變數。需要特別指出的是,靜態變數儲存在靜態儲存區,所以不入棧。當本次函式呼叫結束後,按照棧後進先出的順序退棧,即區域性變數先出棧,然後是老ebp和返回位址,然後是各個引數,最後棧頂指標指向最開始存的位址,也就是主函式中的下一條指令,程式由該點繼續執行。

你不知道的 和

開發中,編寫有一定逼格的 是每個程式猿都追求的。經常用來判斷的符號 和 也經常用來定義變數哦,你知道嗎?邏輯與 在有乙個運算元不是布林值的情況下,就不一定返回布林值。比如以下情況 1 第乙個運算元是物件,返回第二個數 var myinfo console.log myinfo 2 輸出22 第二個運...

你不知道的box shadow

我們可以僅使用乙個div利用shadow配合animation實現很多豐富的效果 github 求 必需。水平陰影的位置。允許負值。v shadow 必需。垂直陰影的位置。允許負值。blur 可選。模糊距離。spread 可選。陰影的尺寸。color 可選。陰影的顏色。請參閱 css 顏色值。ins...

你不知道的 gitignore

乙個.gitignore檔案顯式地指定了哪些檔案不應被git追蹤,即被git忽略掉。在被gitignore之前已經被git追蹤的檔案不受gitignore規則的影響。關於gitignore規則的詳情請繼續往下看。gitignore檔案中的每一行都指定了一種匹配模式。通常來說,git會從多個可能的規則...