1樓:建水竹滑彰
定義棧時會申請一段地址,這段地址就是棧的儲存區,用來儲存棧的資料的。
2樓:匿名使用者
五大記憶體分割槽
在c++中,記憶體分成5個區,他們分別是堆、棧、自由儲存區、全域性/靜態儲存區和常量儲存區。
棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數、函式引數等。
堆,就是那些由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個new就要對應一個delete。如果程式設計師沒有釋放掉,那麼在程式結束後,作業系統會自動**。
自由儲存區,就是那些由malloc等分配的記憶體塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。
全域性/靜態儲存區,全域性變數和靜態變數被分配到同一塊記憶體中,在以前的c語言中,全域性變數又分為初始化的和未初始化的,在c++裡面沒有這個區分了,他們共同佔用同一塊記憶體區。
常量儲存區,這是一塊比較特殊的儲存區,他們裡面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多,在《const的思考》一文中,我給出了6種方法)
明確區分堆與棧
在bbs上,堆與棧的區分問題,似乎是一個永恆的話題,由此可見,初學者對此往往是混淆不清的,所以我決定拿他第一個開刀。
首先,我們舉一個例子:
void f()
這條短短的一句話就包含了堆與棧,看到new,我們首先就應該想到,我們分配了一塊堆記憶體,那麼指標p呢?他分配的是一塊棧記憶體,所以這句話的意思就是:在棧記憶體中存放了一個指向一塊堆記憶體的指標p。
在程式會先確定在堆中分配記憶體的大小,然後呼叫operatornew分配記憶體,然後返回這塊記憶體的首地址,放入棧中,他在vc6下的彙編**如下:
00401028 push 14h
0040102a call operator new (00401060)
0040102f add esp,4
00401032 mov dword ptr [ebp-8],eax
00401035 mov eax,dword ptr [ebp-8]
00401038 mov dword ptr [ebp-4],eax
這裡,我們為了簡單並沒有釋放記憶體,那麼該怎麼去釋放呢?是delete p麼?澳,錯了,應該是delete p,這是為了告訴編譯器:
我刪除的是一個陣列,vc6就會根據相應的cookie資訊去進行釋放記憶體的工作。
好了,我們回到我們的主題:堆和棧究竟有什麼區別?
主要的區別由以下幾點:
1、管理方式不同;
2、空間大小不同;
3、能否產生碎片不同;
4、生長方向不同;
5、分配方式不同;
6、分配效率不同;
管理方式:對於棧來講,是由編譯器自動管理,無需我們手工控制;對於堆來說,釋放工作由程式設計師控制,容易產生memory leak。
空間大小:一般來講在32位系統下,堆記憶體可以達到4g的空間,從這個角度來看堆記憶體幾乎是沒有什麼限制的。但是對於棧來講,一般都是有一定的空間大小的,例如,在vc6下面,預設的棧空間大小是1m(好像是,記不清楚了)。
當然,我們可以修改:
開啟工程,依次操作選單如下:project->setting->link,在category 中選中output,然後在reserve中設定堆疊的最大值和commit。
注意:reserve最小值為4byte;commit是保留在虛擬記憶體的頁檔案裡面,它設定的較大會使棧開闢較大的值,可能增加記憶體的開銷和啟動時間。
碎片問題:對於堆來講,頻繁的new/delete勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式效率降低。對於棧來講,則不會存在這個問題,因為棧是先進後出的佇列,他們是如此的一一對應,以至於永遠都不可能有一個記憶體塊從棧中間彈出,在他彈出之前,在他上面的後進的棧內容已經被彈出,詳細的可以參考資料結構,這裡我們就不再一一討論了。
生長方向:對於堆來講,生長方向是向上的,也就是向著記憶體地址增加的方向;對於棧來講,它的生長方向是向下的,是向著記憶體地址減小的方向增長。
分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:
靜態分配和動態分配。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配由alloca函式進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行釋放,無需我們手工實現。
分配效率:棧是機器系統提供的資料結構,計算機會在底層對棧提供支援:分配專門的暫存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。
堆則是c/c++函式庫提供的,它的機制是很複雜的,例如為了分配一塊記憶體,庫函式會按照一定的演算法(具體的演算法可以參考資料結構/作業系統)在堆記憶體中搜尋可用的足夠大小的空間,如果沒有足夠大小的空間(可能是由於記憶體碎片太多),就有可能呼叫系統功能去增加程式資料段的記憶體空間,這樣就有機會分到足夠大小的記憶體,然後進行返回。顯然,堆的效率比棧要低得多。
從這裡我們可以看到,堆和棧相比,由於大量new/delete的使用,容易造成大量的記憶體碎片;由於沒有專門的系統支援,效率很低;由於可能引發使用者態和核心態的切換,記憶體的申請,代價變得更加昂貴。所以棧在程式中是應用最廣泛的,就算是函式的呼叫也利用棧去完成,函式呼叫過程中的引數,返回地址,ebp和區域性變數都採用棧的方式存放。所以,我們推薦大家儘量用棧,而不是用堆。
雖然棧有如此眾多的好處,但是由於和堆相比不是那麼靈活,有時候分配大量的記憶體空間,還是用堆好一些。
無論是堆還是棧,都要防止越界現象的發生(除非你是故意使其越界),因為越界的結果要麼是程式崩潰,要麼是摧毀程式的堆、棧結構,產生以想不到的結果,就算是在你的程式執行過程中,沒有發生上面的問題,你還是要小心,說不定什麼時候就崩掉,那時候debug可是相當困難的:)
對了,還有一件事,如果有人把堆疊合起來說,那它的意思是棧,可不是堆,呵呵,清楚了?
堆區、棧區、全域性區都有什麼區別
3樓:使用氟
a p m 全域性資料區
bc q w 棧
其中 w p 開闢的空間在堆裡面。
棧和堆是一種資料結構 可以看成容器。
棧和堆一般相對於執行緒 你可以理解成一個函式 函式有一個棧,申請的變數就在這裡放著。
所有函式共享一個堆 ,動態申請的變數在這裡放著 (是空間,不是指標的變數,指標變數仍然在棧裡面。)
全域性變數區是相對於程式來說的,組合語言裡面說 的叫做資料段。
說這麼多沒什麼用 學習多了就會了。一個人一個理解,沒有標準的答案。但是說的基本上都是一個意思。
什麼是棧?
4樓:匿名使用者
棧的定義:棧是一種特殊的表這種表只在表頭進行插入和刪除操作。因此,表頭對於棧來說具有特殊的意義,稱為棧頂。相應地,表尾稱為棧底。不含任何元素的棧稱為空棧。
棧的邏輯結構:假設一個棧s中的元素為an,an-1,..,a1,則稱a1為棧底元素,an為棧頂元 素。
棧中的元素按a1 ,a2,..,an-1,an的次序進棧。在任何時候,出棧的元素都是棧頂元素。
換句話說,棧的修改是按後進先出的原則進行的.因此,棧又稱為後進先出(last in first out)表,簡稱為lifo表。所以,只要問題滿足lifo原則,就可以使用棧。
notice:換句話說,棧就是可以一個元素進後,可以接著進行輸出的表.
這道題各個選項的進出次序為:
a:進,出,進,出,進,出,進,進,出,出,進,出,進,出b:進,進,出,進,出,出,進,進,進,出,出,進,出,出c:
進,出,進,進,進,進,出,出,出,出,進,出,進,出d:進,進,進,進,出,出,進,進,出,出,出,出,進,出e:錯誤.
原因自己仿照上面做做看.
所以這道題選e.明白了嗎?
5樓:明推暗量
一、漢字
棧,zhan,從木從戔。牲口棚,馬鵬。
基本釋義
儲存貨物或供旅客住宿的房屋:貨棧。客棧。棧房。
竹木編成的遮蔽物或其他東西:馬棧(養馬的竹木棚)。棧車(古代用竹木編成棚的車子)。
用木料或其他材料架設的通道:棧道。棧橋(一種形似橋樑的建築物,用於裝卸貨物、上下旅客等)。
通過,越過:棧山航海。
二、計算機術語
定義:棧是限定僅在表頭進行插入和刪除操作的線性表。要搞清楚這個概念,首先要明白」棧「原來的意思,如此才能把握本質。
"棧「者,儲存貨物或供旅客住宿的地方,可引申為倉庫、中轉站,所以引入到計算機領域裡,就是指資料暫時儲存的地方,所以才有進棧、出棧的說法。
首先系統或者資料結構棧中資料內容的讀取與插入(壓入push和 彈出pop)是兩回事!插入是增加資料,彈出是刪除資料 ,這些操作只能從棧頂即最低地址作為約束的介面介面入手操作 ,但讀取棧中的資料是隨便的沒有介面約束之說。很多人都誤解這個理念從而對棧產生困惑。
而系統棧在計算機體系結構中又起到一個跨部件互動的媒介區域的作用 即 cpu 與記憶體的交流通道 ,cpu只從系統給我們自己編寫的應用程式所規定的棧入口線性地讀取執行指令, 用一個形象的詞來形容它就是pipeline(管道線、流水線)。cpu內部互動具體參見 eu與biu的概念介紹。
棧作為一種資料結構,是一種只能在一端進行插入和刪除操作的特殊線性表。它按照先進後出的原則儲存資料,先進入的資料被壓入棧底,最後的資料在棧頂,需要讀資料的時候從棧頂開始彈出資料(最後一個資料被第一個讀出來)。棧具有記憶作用,對棧的插入與刪除操作中,不需要改變棧底指標。
棧是允許在同一端進行插入和刪除操作的特殊線性表。允許進行插入和刪除操作的一端稱為棧頂(top),另一端為棧底(bottom);棧底固定,而棧頂浮動;棧中元素個數為零時稱為空棧。插入一般稱為進棧(push),刪除則稱為退棧(pop)。
棧也稱為後進先出表。
棧可以用來在函式呼叫的時候儲存斷點,做遞迴時要用到棧!
以上定義是在經典電腦科學中的解釋。
棧,元素入棧時,是直接放到棧底,還是先放到棧頂
你把棧看成是一個堆放盤子的箱子,入棧就是往箱子中放盤子,即放在棧頂,出棧就像從箱子中取出盤子,也是從棧頂拿出。堆,列隊優先,先進先出。棧,先進後出 望採納 為什麼說棧底元素總是最先被插入的元素,從而也是最後才能被刪除,不是說棧底不允許被插入刪除嗎 你這句話沒有理解嗎?棧底元素總是最先被插入的元素,從...
什麼是考研a區和b區什麼是考研A區和B區?
a區和b區指的是一區和二區。研究生考試選拔要求因層次 地域 學科 專業的不同而有所區別。考研國家線劃定分為a b類,其中一區實行a類線,二區實行b類線。一區包括 北京 天津 河北 山西 遼寧 吉林 黑龍江 上海 江蘇 浙江 安徽 福建 江西 山東 河南 湖北 湖南 廣東 重慶 四川 陝西。二區包括 ...
誰能跟我講一下進棧為什麼要SP減2出棧為什麼是SP
堆疊的兩條操作指令push 進棧 pop 出棧 其指令格式為 push opd pop opd 其中opd是16位的運算元,可以是暫存器或儲存器運算元而記憶體空間 包括棧空間 是以位元組 8位 為單位進行儲存的,所以無論進棧或出棧,都要使用棧空間的兩個位元組。即在做進棧時,其棧指標 sp 要sp 2...