1.1 先看看c++對記憶體分為哪幾個區?
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。想知道為什麼效率高嗎?因為關於棧的操作如push整合在處理器的指令集中,效率很高,但是分配的記憶體容量有限。
2、堆區(heap) — 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。
3、全域性區(靜態區)(static)—,全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。
4、文字常量區—常量字串就是放在這裡的。
5、程式**區—存放函式體的二進位制**。
1.2 再給面試官談談new/delete和malloc/free的區別?
1、像我們的new/delete和malloc/free就是在上面所說的堆區上操作。程式設計師申請了記憶體,用完要記得釋放,否則就記憶體洩露了。而且多次申請釋放,會造成堆區碎片,這個需要注意下。
2、new/delete是操作符,而malloc/free是函式。前者可以被過載。前者可以有建構函式和析構函式。前者返回的某種型別物件的指標,後者返回void指標。
2.基於問題1,深入談談堆和棧
1、申請方式:
棧:函式內的區域性變數:int a = 10;
堆:new / malloc
2、申請後的系統響應:
棧:只要申請的空間大小《棧的剩餘空間,棧就分配。
堆:因為new,malloc都是c++封裝的,裡面做了這樣的事:首先明白windows有這麼乙個記錄空閒空間位址的鍊錶,c++遍歷該鍊錶,先找到第乙個空閒空間大小大於程式設計師申請的空間大小的位址(堆節點),將該堆節點從鍊錶中刪除,把該節點的空間分配給程式。對於大多數系統,會在這塊記憶體空間中的首位址處記錄本次分配的大小,這樣,**中的delete語句才能正確的釋放本記憶體空間。由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。
3、申請大小:
棧:預設是1m?還是2m?
堆:看系統的虛擬記憶體有多大了。(請記住堆是乙個節點為空閒記憶體空間的鍊錶。。)堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存的空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。
4、申請效率:
棧:速度快,push,pop等指令都內建在處理器了,能不快嗎?
堆:相對慢(為什麼慢,可以看2,就知道它在申請的時候幹了多少事),還容易產生記憶體碎片。不過容量大,操作方便。
5、儲存內容:
棧(依次是):
主函式中後的下一條指令位址
然後是函式的各個引數(在大多數的c編譯器中,引數是由右往左入棧的)
函式中的區域性變數
堆:程式設計師隨意安排。
6、訪問效率:
先看看這段**:
int main()
這是在函式內,char陣列c,是在棧上。
char *p = "1234567890" ,其中雖然*p也是在棧上,但是"1234567890"在常量區。
再看看它們對應的彙編**:
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
可以看到在棧上的c只要兩行就能取到內容,而p要先去把常量區的內容放到edx中,再訪問。
說明純棧操作,效率是要高一些的。
7、總結
看看乙個經典**就什麼都懂了:
int a = 0; //全域性初始化區
char *p1; //全域性未初始化區
main()
C 記憶體管理 記憶體分配
1 c 編譯的程式占用的記憶體分類 1 棧區 stack 程式執行時由編譯器自動分配,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。程式結束時由編譯器自動釋放。2 堆區 heap 在記憶體開闢另一塊儲存區域。一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注...
記憶體分配管理
系統中的記憶體分為棧 堆 全域性區 區 棧 由編譯器自動分配釋放,參訪函式的引數值,區域性變數,函式棧幀,函式呼叫過程。堆 由程式設計師自行分配想要的空間大小,c中的malloc等函式,c 中的new 全域性區 資料區 存放的是全域性變數和靜態變數,初始化的存在一起,未初始化的放一起,程式結束後由系...
記憶體分配 Go記憶體管理 記憶體分配一
go作為乙個比較新晚 新 的語言,自然借鑑前輩們的優點,比如說語言本身負責記憶體管理 對協程和高併發的高優支援 簡單高效的語法等。本篇及後續的幾篇要講的就是還沒提到的比較複雜的記憶體管理。學習記憶體管理 分配 前,如果有jvm的記憶體管理的基礎,會變得非常簡單,如果是第一次接觸記憶體管理,在看完go...