關於對堆疊的理解

2021-10-21 09:04:50 字數 1888 閱讀 1597

棧區(stack):是由系統或者編譯器進行分配和釋放,存放區域性變數的值、函式的引數值等,操作方式類似於資料結構中的棧。

堆區(heap):一般是由程式設計師自己進行分配記憶體空間和釋放的,假設程式設計師沒有對其進行釋放,在程式結束時,有時候作業系統會對其進行系統**,操作方式類似於鍊錶。

全域性區(靜態區static):存放的是全域性變數或者靜態變數,並且是放在一塊的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和靜態變數存放在相鄰的一塊區域內。在程式結束後由系統進行釋放。

文字常量區:常量字串所佔的空間就是存放在這裡的。程式結束後由系統進行釋放。

程式**區:一般是存放函式體的二進位制**。程式結束後由系統進行**。

1、從申請方式來談

棧:是由系統自動分配的,例如定義乙個區域性變數int b ;系統會自動在棧中為b開闢空間。

堆:需要程式設計師自己去申請記憶體空間,並且指明申請的大小,在c中用malloc函式,在c++中使用new來開闢新空間。

如:

p1 =

(char*)malloc(10)

;int *p2 = new int(20)

;

但注意p1和p2本身是在棧中的,分配的記憶體空間大小是在堆中的。

2、從申請後系統的響應來談:

棧:只要棧的剩餘空間大於申請所需要的空間,系統就會自動為程式分配記憶體,否則會報異常overflow棧溢位。

堆:對於堆,我們知道在作業系統中有乙個記錄空閒記憶體位址的鍊錶,當系統收到程式申請記憶體時,會遍歷該鍊錶,尋找第乙個空間大於所申請空間的堆節點,然後將該節點從鍊錶中刪除,並將該節點所佔的空間分配給程式。對於大多數系統,會將這塊記憶體的首位址處記錄本次分配空間的大小,這樣,我們在使用delete函式的時候,系統就會知道需要**多少記憶體空間。如果分配給程式的記憶體空間大小和所申請的不一致,系統還會將多餘的那部分進行**,重新放入鍊錶中。

3、從申請大小的限制來談:

棧:在windows環境下,棧的增長方向是由高位址指向低位址的,是一塊連續的記憶體區域,意思就是棧頂的位址和站的最大容量是由系統預先設定好的,在windows環境下,棧的大小是2mb,這是在系統編譯階段確定的。如果申請的空間找過棧空間,將會提示overflow,棧溢位異常。因此,能從棧獲得空間大小是極小的。

堆:首先堆是由鍊錶進行儲存空閒的記憶體位址的,所以堆是不連續的記憶體區域。堆的增長方向是由低位址指向高位址的,並且堆的大小受限於計算機系統的虛擬記憶體。所以堆獲得空間比較靈活,也比較大。

4、從申請效率來談:

棧:首先棧是由系統進行分配的,並且空間大小固定,速度較快,但是對於程式設計師來說是不可控的。

堆:堆是由程式設計師自己申請並分配空間(c:malloc,c++:new),大小確定,相對於系統分配,比較可控,使用方便。但是速度比較慢,而且容易產生記憶體碎片,造成記憶體空間的浪費。

另外,在windows環境下,最好的方式使用virtualalloc分配記憶體,不在棧,也不在堆,它是直接在程序的位址空間中保留一塊記憶體。雖然用起來不方便,但是速度最快,也最靈活。

全域性變數放在資料段;函式內部變數static int num放在資料段;函式內部變數char* p = 「aaa」,p的位置在棧,指向的空間的位置在資料段;函式內部變數char *p = new char;p的位置在棧,指向空間的位置在堆;

關於對defer的理解

function init init script 如果你能看到這一句,那就是說沒有達到我所要的效果 div 在ie6和firefox2下完全不一樣 ie6中最後執行結果是ok,而firefox中是 如果你能看到這一句,那就是說沒有達到我所要的效果 我覺得defer這個東西 有推遲執行的意思,ie6...

關於對defer的理解

script defer function init init script divid div 如果你能看到這一句,那就是說沒有達到我所要的效果 imgsrc div 在ie6和firefox2下完全不一樣 ie6中最後執行結果是ok,而firefox中是 如果你能看到這一句,那就是說沒有達到我所...

關於對指標理解

在c語言中,記憶體單元的位址稱為指標,打個比喻。代表 0x2000位址代表門牌號,取位址符。i pointer 指標變數,它的內容是位址量 i pointer 指標的目標變數,它的內容是資料 i pointer 指標變數占用記憶體的位址 i pointer 內容位址量 i 取i位址 i pointe...