複製鏈接
請複製以下鏈接發送給好友

棧地址

鎖定
(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。這一端被稱為棧頂,相對地,把另一端稱為棧底。棧地址是指棧頂的地址。當為局部變量分配棧內存時,系統就將局部變量存入到棧的某個內存塊中;當子函數運行結束局部變量應當被釋放時,系統再將這些存入局部變量的棧內存中的數據清除掉,恢復原來沒有被初始化的狀態。
中文名
棧地址
外文名
stack address
學    科
計算機科學與技術
基本釋義
棧頂地址
功    能
對數據項進行插入和刪除
基本操作
入棧出棧

棧地址基本概念

(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。這一端被稱為棧頂,相對地,把另一端稱為棧底。不含任何元素的棧稱為空棧。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素 [1] 
如圖1所示:假設一個棧S中的元素為
,則稱a1為棧底元素,an為棧頂元素。
圖1 棧 圖1 棧
棧地址是指棧頂的地址。在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的説是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。

棧地址棧與棧地址的操作

棧是由系統自動分配和回收的內存。如一個子函數被調用時,系統會將函數內的局部變量的內存單元分配到棧上,當函數執行完畢時系統自動釋放所分配的棧地址單元。棧的修改是按後進先出的原則進行的。棧又稱為後進先出(Last In First Out)表,簡稱為LIFO表。
在計算機系統中,棧則是一個具有以上屬性的動態內存區域。程序可以將數據壓入棧中,也可以將數據從棧頂彈出。在i386機器中,棧頂由稱為esp的寄存器進行定位。壓棧的操作使得棧頂的地址增大,彈出的操作使得棧頂的地址減小。

棧地址棧和棧地址的特點

以下是棧和棧地址在程序運行中的特點:
(1)棧經常與 sp 寄存器一起工作,最初 sp 指向棧頂(棧的高地址),即棧地址。
(2)CPU 用 push 指令來將數據壓棧,用 pop 指令來彈棧。當用 push 壓棧時,sp 值減少(向低地址擴展)。當用 pop 彈棧時,sp 值增大。存儲和獲取數據都是 CPU 寄存器的值。
(3)當函數被調用時,CPU使用特定的指令把當前的 IP 壓棧。即執行代碼的地址。CPU 接下來將調用函數地址賦給 IP ,進行調用。當函數返回時,舊的 IP 被彈棧,CPU 繼續去函數調用之前的代碼。
(4)當進入函數時,sp 向下擴展,擴展到確保為函數的局部變量留足夠大小的空間。如果函數中有一個 32-bit 的局部變量會在棧中留夠四字節的空間。當函數返回時,sp 通過返回原來的位置來釋放空間。
(5)如果函數有參數的話,在函數調用之前,會將參數壓棧。函數中的代碼通過 sp 的當前位置來定位參數並訪問它們。
(6)函數嵌套調用和使用魔法一樣,每一次新調用的函數都會分配函數參數,返回值地址、局部變量空間、嵌套調用的活動記錄都要被壓入棧中。函數返回時,按照正確方式的撤銷。
(7)棧要受到內存塊的限制,不斷的函數嵌套/為局部變量分配太多的空間,可能會導致棧溢出。當棧中的內存區域都已經被使用完之後繼續向下寫(低地址),會觸發一個 CPU 異常。這個異常接下會通過語言的運行時轉成各種類型的棧溢出異常。

棧地址棧地址的分配

棧的分配和釋放可以這樣子理解:棧內存塊在計算機中不可能會移動,它的地址已經被固定。系統分不分配它,它就在那裏。當為局部變量分配棧內存時,系統就將局部變量存入到棧的某個內存塊中;當子函數運行結束局部變量應當被釋放時,系統再將這些存入局部變量的棧內存中的數據清除掉,恢復原來沒有被初始化的狀態。
在函數調用時,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變量。注意靜態變量是不入棧的。當本次函數調用結束後,局部變量先出棧,然後是參數,最後棧頂指針指向函數的返回地址,也就是主函數中的下一條指令的地址,程序由該點繼續運行。

棧地址棧、堆、靜態存儲區和常量存儲區

在C++中,內存分成4個區,他們分別是堆、棧、靜態存儲區和常量存儲區。下面是四個區的特點與區別:
(1)棧:就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變量的存儲區。裏面的變量通常是局部變量、函數參數等。
(2)堆:又叫自由存儲區,它是在程序執行的過程中動態分配的,它最大的特性就是動態性。堆就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那麼在程序結束後,操作系統會自動回收。
(3)靜態存儲區:所有的靜態對象,全局對象都於靜態存儲區分配。
(4)常量存儲區:這是一塊比較特殊的存儲區,他們裏面存放的是常量,不允許修改。常量字符串都存放在靜態存儲區,返回的是常量字符串的首地址。
棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。
參考資料
  • 1.    厲鵬, 樊穎. 數據結構中棧的應用[J]. 智能計算機與應用, 2008(1):61-62.