程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 關於C++使用指針 堆和棧的區別分析

關於C++使用指針 堆和棧的區別分析

編輯:C語言基礎知識

數據在內存的存放有以下幾種形式

1.棧區--由編譯器自動分配並且釋放,該區域一般存放函數的參數值,局部變量的值等,
2.堆區--一般由程序員分配釋放,如果程序員不釋放,程序結束的時候才會被操作系統回收,
3.寄存器區--用來保存棧頂指針和指令指針
4.全局去--也是靜態區,全局變量和靜態變量都是存儲在一起的,初始化的全局變量和靜態變量都存儲在一塊,為初始化的全局變量和靜態變量在相鄰的另一個區域,程序結束後由系統釋放。
5.文字常量區--常量字符串就是放在這裡的,程序結束後由系統釋放,
6.程序代碼區--存放函數的二進制代碼。

函數參數和局部變量存放在棧中,函數運行結束或者返回系統就釋放了他們所占用的內存空間,但是全局變量不會被系統釋放掉。全局的只有在程序結束後才會被系統所釋放,而且由於全局變量被所有的類成員和函數所共享,很容易被修改,為了解決這一問題
我們會使用堆

堆棧的區別

1.申請方式的不同

堆是程序員自己申請
而棧則是有程序判斷局部變量或者函數 系統來自動分配

2.系統的響應不同

棧-只要棧的剩余空間大於所申請的空間,系統將為程序提供內存,否則將提示棧溢出 overflow

堆- 系統收到程序中申請的控件後,會遍歷一個操作系統用來記錄內存控件地址得鏈表,當找到一個空間大於所申請控件的堆結點後就會將該節點從記錄內存空閒地址的鏈表中刪除,並將結點的內存分配給程序,然後在這塊區域的首地址處記錄分配的大小,     這樣我們在使用delete來釋放內存的時候,delete才能正確的識別並刪除該內存區域的所有變量,另外我們申請的內存空間與堆結點上的內存空間不一定相等,這時候系統就會自動將堆結點上的多出來的一部分內存空間回收到空閒鏈表中

3、空間的大小不同

棧-在windows狀態下,棧是一塊連續的內存的區域,它的大小是2M,也有的說1M,總之這個數值是一編譯的時候就確定的常數,是由系統預先根據棧頂的地址和棧的最大容量定義好的,加入你的數據申請的內存空間超過棧的空間,就會提示overflow,所以別指望棧能夠存儲比較大的數據。

堆-堆是不連續的內存區域,各塊區域由鏈表將他們串起來,這些串聯起來的內存空間叫做堆,他的大小是由系統中虛擬的內存來定的,因此獲得的空間比較大,而且獲得空間的方式也比較靈活。

4.執行效率的不同

棧-棧由系統自動分配,因此速度比較快,但是程序員不能對其進行操作。
堆-堆是程序員分配的內存,     一般速度比較慢,而且容易產生內存碎片,不過用起來很方便。

5.執行函數的不同

棧-在函數調用的時候,第一個進棧的是被調用函數下一行的內存地址,其次是函數的參數,假如參數多余一個,那麼次序是從左往右,最後才是函數的局部變量。

由於棧的先進後出原則,函數結束時正好相反,先是局部變量先出棧,然後是參數,次序是從左向右,這時所偶的變量都出棧,指針自然的第一個進棧的那行內存地址,也就是被調用函數的下一行內存地址,程序根據該地址跳轉到調用函數的下一行自動執行。

由於棧的先進後出原則,所以他永遠不可能產生內存碎片

堆--堆是一大堆不連續的內存區域,在系統中由鏈表將他們串聯起來,因此在使用的時候必須由程序員來安排,他的機制是很復雜的,有時候為了分配一塊合適的內存,程序員需要按照一定的算法在堆內存中搜索可用的足夠大的空間,如果沒有滿足條件的空間,那麼就要向內存中發出申請一部分內存空間,這樣才能有機會分配足夠大的內存,然後將計算後的數值返回,顯然堆的運行效率比棧低很多,而且容易產生碎片,但是好處是堆可以存儲相當的大的數據,並且一些細節可以由程序員來安排。

以上就是堆棧的區別 但是在應用中的取捨還是具體問題具體分析

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved