堆棧:堆棧被用作臨時暫存區,供當前正在執行的代碼塊以及任何稱爲當前塊的塊和任何稱爲該塊的塊等等使用。當前塊存在時,它所使用的局部變量被遺忘。正如名稱所示,堆棧以後進先出的方式使用。
該堆棧最重要的用途之一是跟蹤當前的調用鏈。當一個函數調用另一個函數時,調用者將下一條指令的地址(返回地址)推入堆棧。當每個函數退出時,它會將其調用者的返回地址從堆棧中彈出,並繼續執行從該地址開始的代碼。它也用於在調用者和被調用者之間傳遞函數參數和返回值。
堆:堆是不同的 - 有沒有特定的順序。如果你想在一段代碼中分配內存,並讓該內存超出塊的末尾,你可以將它分配到堆上。當然,您還需要在某處存儲指針/引用,以便其他代碼可以找到該內存;大多數語言提供住宿。
速度:速度的差異並不是由於內存本身的任何屬性 - 正如你在你的問題中所說的那樣,棧和堆通常都在相同的物理內存中。在堆棧中分配空間很快,原因在於堆棧的LIFO性質:如果將某些東西壓入堆棧,只能有一個地方結束。相比之下,在堆上分配塊需要在內存中找到足夠大的連續空閒區域。堆棧分配可以像單條指令一樣快;堆分配需要調用內存分配功能,如malloc()
。
靜態與動態:在堆上分配內存是動態的 - 是否分配塊和塊的大小可以根據程序在運行時接收的輸入來確定。在堆上分配的內存區域甚至可以根據需要調整大小。它也可能是也可以動態分配堆棧中的內存(請參閱C標準庫函數alloca()
),但是當前函數退出後該內存將立即丟失。堆棧分配通常是靜態的 - 編譯器確定(非註冊)參數,返回數據和本地變量需要多少空間,並且在調用該函數時生成代碼以在堆棧中保留必要的空間。
示例:想象一下,您正在創建一個文字處理器。您無法提前知道文檔的大小,甚至可能同時使用多少個文檔。與此同時,只要用戶想讓它們保持打開狀態,就希望用戶的文檔保留在內存中。如果您嘗試爲堆棧中的文檔分配內存,您會發現很難一次打開多個文檔,並且您需要創建一個創建,編輯,保存和關閉文檔的函數。在堆上分配空間允許您創建儘可能多的文檔,每個文檔都根據其包含的數據進行適當的大小設置,並避免將文檔的生命週期與任何特定功能的生命週期掛鉤。
總結:簡而言之,堆棧保存變量的值(有時使用寄存器),而堆用於分配將在當前塊的生命週期之外使用的內存。
http://stackoverflow.com/questions/7123936/why-is-there-a-stack-and-a-heap – drdwilcox
http://stackoverflow.com/questions/79923/what-and-where-are堆棧和堆 –