**於李家凱老師的文章.
由c/c++編譯的程式占用的記憶體可以分為一下兩個部分:
堆區(heap):一般由程式設計師分配釋放(比如malloc/free,new/delete),如果程式設計師不釋放,程式結束時可能會由作業系統進行**。需要注意的是它和資料結構個中的堆是兩碼事,分配方式上堆類似於鍊錶。
棧區(stack):由編譯器自動分配和釋放,存放函式的引數值、區域性變數等。它的操作方式和資料結構中的棧相似。
全域性區(static):全域性變數和靜態變數是存放在一塊的,初始化全域性變數和靜態變數是在一塊區域的,而未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域,程式結束後系統自動釋放。
文字常量區:常量字串存放與於此,程式結束後系統自動釋放。
程式**區:存放函式體的二進位制**。
example:
int a = 0; // 全域性初始化區
char *p1; // 全域性未初始化區
main()
棧:系統自動分配。比如,申明乙個區域性變數int a;系統自動在棧中為a開闢空間。
堆:需要程式設計師自己申請,並指明大小。比如:
p2 = (char *)malloc(10);
這句語句中p2是存在棧裡的,但是他們指向的申請到的記憶體是在堆裡的。
堆:首先應該知道作業系統有乙個記錄空閒記憶體位址的鍊錶。當系統收到程式的申請的時候,會遍歷該鍊錶,尋找到第乙個空間大於所申請空間的堆節點,然後將該節點從空閒結點鍊錶中刪除,再把該節點的空間分配給程式;另外,對於大多數系統,會在這塊記憶體空間的首位址處記錄本次分配的大小,這樣delete語句才能正確的釋放本記憶體空間。另外,由於找到的堆節點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。
棧:只要棧的剩餘空間大於所申請的空間,系統就能為程式提供記憶體,否則會報異常提示棧溢位。
堆:堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由系統使用鍊錶來儲存空閒記憶體位址的,這些是不連續的。而鍊錶的遍歷方向是低位址到高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見堆的空間比較靈活也比較大。
棧:棧是從低位址到高位址擴充套件的,是一塊連續的記憶體區域。這句話的意思是說站定的位址和棧的最大容量是系統預先規定好的。(windows裡棧的大小一般是1m或者2m)如果申請的空間超過棧的剩餘空間就會提示stack overflow。 因此,從棧獲得的空間比較小。
堆:是由malloc/new分配的記憶體,一般速度比較慢,而且容易產生記憶體碎片,不過用起來最方便。
棧:由系統自動分配,速度較快。但程式設計師是無法控制的。
堆:一般是在堆的頭部用乙個位元組存放堆的大小。堆中的具體內容有程式設計師安排。
棧:在函式呼叫時,第乙個進棧的是主函式中的下一條指令(函式呼叫語句的下一條可執行語句)的位址,然後是函式的各個引數,在大多數的c編譯器中,引數是由右往左入棧的,然後是函式中的區域性變數。注意靜態變數是不入棧的。當本次函式呼叫結束後,區域性變數先出棧,然後是引數,最後棧頂指標指向最開始存的位址,也就是主函式中的下一條指令,程式由該點繼續執行。
char s1 = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在執行時刻賦值的;
而bbbbbbbbbbb是在編譯時就確定的;
但是,在以後的訪問中,在棧上的陣列比指標所指向的字串(例如堆)快。
比如:#include
void main()
對應的彙編**
10: a = c[1];
00401067 8a 4d f1 mov cl,byte ptr [ebp-0fh]
0040106a 88 4d fc mov byte ptr [ebp-4],cl
11: a = p[1];
0040106d 8b 55 ec mov edx,dword ptr [ebp-14h]
00401070 8a 42 01 mov al,byte ptr [edx+1]
00401073 88 45 fc mov byte ptr [ebp-4],al
第一種在讀取時直接就把字串中的元素讀到暫存器cl中,而第二種則要先把指標值讀到edx中,在根據edx讀取字元,顯然慢了。 記憶體學習筆記 堆 棧等
一般來說,程式就是與資料打交道,在執行某一程式功能的時侯,將該功能所需要的資料載入到記憶體中,然後在執行完畢的時候釋放掉該記憶體。1 區 程式的 函式 放入 區,函式指標就指向 區,為唯讀區。2 全域性區 用來存放全域性變數和static靜態變數,在main執行之前分配全域性區,可讀可寫。3 bss...
Lua學習筆記 lua堆疊
首先了解一下c 與lua之間的通訊 假設在乙個lua檔案中有如下定義 hello.lua檔案 請注意紅色數字,代表通訊順序 1 c 想獲取lua的myname字串的值,所以它把myname放到lua堆疊 棧頂 以便lua能看到 2 lua從堆疊 棧頂 中獲取myname,此時棧頂再次變為空 3 lu...
C語言學習筆記 堆疊
我是乙個軟體開發工程師,但是我覺得我什麼都不是,原因很簡單,c語言學的太差 對系統了解的太少 今天開始先主要學習一下c語言中的難點理論知識。今天主要是對堆疊進行乙個總結。昨天去華為面試硬體平台部門,他們的經理給我面試的,問我硬體,我沒有經驗,問我c語言熟悉嗎?答曰 熟悉,但是我現在一直用的是lpc語...