其實我們都知道,計算機內存本來就是一塊內存,沒有堆棧之分。
在學編程的時候,我們應該都聽過一句話 “如果程序結束之后仍然想要訪問那一段數據就要用堆”,我想這個其實就是你疑問的關鍵了,堆和棧都有其自己的獨特性,可能你了解這兩個東西,但是我還是解釋下,以免別的小伙伴在看答案的時候,不知道。
棧:就像我第一句話說的,本沒有什么堆棧之分,但是編程語言的出現,就有了一個概念“函數”,這個函數之間是可以相互調用的(就像我們傳遞東西,比如:胡小然 將東西傳遞 胡小然2 將東西傳遞 胡小然3,之后需要從后面向前面反饋傳遞結果,這個傳遞的過程我們就可以理解為調用),那就出現了前后之分,這就是調用隊列了,那這個隊列有個什么特點呢,那就是先被調用進入隊列的要最后出去,就是我們常說的先進后出(FILO),那么這時棧就出現了,而且它還有一個特點那就是線程獨有(所以可以存放我們的臨時變量),生命周期是隨線程的。當然我所說的是內存棧的意思,其實“棧”就是個數據結構,是一種限定僅在表尾進行插入和刪除操作的線性表,這個特性不正好是符合我剛才說的FILO嘛。所以你可以這么理解c++或者java(jvm)中的內存棧的概念,就是編程語言的作者為了管理內存使用了“棧”這種數據結構(說的再細點就是現代CPU體系結構決定了棧是管理函數調用和局部變量的最佳數據結構。因為CPU已經提供了現成的指令)。
堆:可算是一種特殊的數據結構,好像我們經常使用的二叉樹。內存堆這個解釋起來就更簡單了,就是一塊能自由分配的內存。它允許程序在運行時動態地申請某個大小的內存空間,比如:程序員向操作系統申請一塊內存,當系統收到程序的申請時,會遍歷一個記錄空閑內存地址的鏈表,尋找第一個空間大于所申請空間的堆結點,然后將該結點從空閑結點鏈表中刪除,并將該結點的空間分配給程序。其特點就是分配的速度較慢,地址不連續,容易碎片化并且是由程序員申請,同時也必須由程序員負責銷毀,否則導致內存泄露。像在java這種高級語言中,我們不比擔心內存回收的問題,那是因為jvm已經在幫我們處理了。
上面說了這么多,就是想說明一下內存棧和內存堆出現的意義和作用,所以答案就出來了,那就是不能“只用堆或者全部只用棧”那樣我們程序的調用和數據的存儲都會出現問題。
好了,上面只是我自己一些理解,不對的地方還請大家指出,也希望對題主的疑問有幫助。