現在的位置: 首頁 > web前端 > 正文

堆棧溢出原理是什麼

2020年07月21日 web前端 ⁄ 共 1110字 ⁄ 字型大小 評論關閉

  堆棧(Stack)是一種抽象數據結構,是一組相同數據類型的組合,所有的操作均在堆棧頂端進行,具有「後進先出」的特性,即最後一個放入堆棧中的物體總是被最先拿出來。堆棧中兩個最重要的是PUSH(進棧)和POP(出棧),PUSH操作在堆棧的頂部加入一個元素,POP操作相反,在堆棧頂部移去一個元素,並將堆棧的大小減一。水滿則溢,堆棧是有一定容量限制的,當超出了該容量限制,就會發生溢出。


  堆棧溢出是什麼


  內存中的堆與棧


  事實上,堆和棧是不同的數據結構概念,堆棧溢出也可細化為堆溢出和棧溢出兩種。棧有兩個特性:只能從棧的頂端存取數據;數據的存取符合後進先出的原則。所謂後進先出,其實就如同自助餐中餐盤在桌面上一個一個往上疊放,在取用時先拿最上面的餐盤,這是典型的堆棧概念的應用。堆是一種樹結構,準確地說是一個完全二叉樹。


  在內存中,當一個可執行程序被裝入到內存時,主要包括兩個部分:代碼和數據。代碼會被裝入到內存中的代碼區,數據區又由3部分組成:①全局變數:根據其是否有初始值,被裝入到內存中的未初始化數據區和初始化數據區;②局部變數:在函數調用發生時存放在棧中;③動態內存空間:在程序運行時申請的動態內存空間存放在堆中。


  棧區(stack)是後進先出的結構,向低地址進行擴展,是一塊連續的內存區域,棧頂的地址和棧的最大容量是系統預先規定的,只要棧的剩餘空間大於所申請空間,系統將為程序提供內存,否則將報異常來提示棧發生溢出。棧空間是系統自動分配、釋放的,存放函數的參數值、局部變數的值等。一般來說,進棧的順序首先為主函數中的下一條指令(函數調用語句的下一條可執行語句)的地址先進棧,其次是參數由右往左依次進棧,最後是函數中的局部變數進棧,出棧順序與進棧順序相反,對於程序來說,出棧就意味著函數執行完畢,函數空間將被系統完全釋放掉。


  堆區一般由程序員自己申請,並指明大小,程序最後進行釋放,若程序員不釋放,程序結束時可能由操作系統回收(注意,如果是C/C++語言,程序不進行對空間回收,而Java語言中有專門的垃圾回收器進行回收),堆區與數據結構中的堆有所不同,分配方式類似於鏈表。堆區向高地址擴展。


  堆棧溢出原理


  堆棧溢出是說堆區和棧區的溢出,二者同屬於緩衝區溢出。從上面關於堆區和棧區的解釋可以看出,一旦程序確定,堆棧內存空間的大小就是固定的,當數據已經把堆棧的空間佔滿時,再往裡面存放數據就會超出容量,發生上溢;當堆棧中的已經沒有數據時,再取數據就無法取到了,發生下溢。需要注意的是,棧分為順序棧和鏈棧,鏈棧不會發生溢出,順序棧會發生溢出。


  總之,堆棧溢出給大家簡單的介紹了一些,希望大家多看看。


  

抱歉!評論已關閉.