c 面試 堆疊記憶體

2021-10-04 11:07:26 字數 3846 閱讀 9096

乙個由c/c++編譯的程式占用的記憶體分為幾個部分

2、堆區(heap):一般是由程式設計師分配釋放,若程式設計師不釋放的話,程式結束時可能由os**,值得注意的是他與資料結構的堆是兩回事,分配方式倒是類似於資料結構的鍊錶。

3、全域性區(靜態區

static):也叫靜態資料記憶體空間,儲存全域性變數和靜態變數,全域性變數和靜態變數的儲存是放一塊的,初始化的全域性變數和靜態變數放一塊區域,沒有初始化的在相鄰的另一塊區域,程式結束後由系統釋放。

4、文字常量區:常量字串就是放在這裡,程式結束後由系統釋放。

5、程式**區:存放函式體(類成員函式和全域性區)的二進位制**。

int a = 0; 全域性初始化區

char *p1; 全域性未初始化區

main()

int b;// 棧

char s = 「abc」; //"abc"在常量區,s在棧上。

char *p2; //棧

char *p3 = 「123456」; //123456\0";在常量區,p3在棧上。

static int c =0; //全域性(靜態)初始化區

p1 = (char *)malloc(10);

p2 = (char *)malloc(20);

//分配得來得10和20位元組的區域就在堆區。

strcpy(p1, 「123456」); //123456\0放在常量區,編譯器可能會將它與p3所指向的"123456"優化成乙個地方。

三種記憶體分配方式

1靜態儲存區分配:內存在程式編譯的時候已經分配好,這塊內存在程式的整個執行期間都存在。例如全域性變數,static變數。

2在棧上建立:在執行函式時,函式內區域性變數的儲存單元可以在棧上建立,函式執行結束時,這些記憶體單元會自動被釋放。

棧記憶體分配運算內置於處理器的指令集,效率高,但是分配的記憶體容量有限。

3從堆上分配:亦稱為動態記憶體分配。

程式在執行的時候使用malloc或者new申請任意多少的記憶體,程式設計師自己負責在何時用free或delete釋放記憶體。

動態記憶體的生命週期有程式設計師決定,使用非常靈活,但如果在堆上分配了空間,既有責任**它,否則執行的程式會出現記憶體洩漏,頻繁的分配和釋放不同大小的堆空間將會產生記憶體碎片。

堆和棧的區別

1 管理方式:棧是由編譯器自動申請和釋放空間,堆是需要程式設計師手動申請和釋放;

2 空間大小:棧是一塊連續的記憶體區域,大小是作業系統預定好的,windows下棧大小是2m(也有是1m,在編譯時確定,vc中可設定)。堆是不連續的記憶體區域(因為系統是用鍊錶來儲存空閒記憶體位址,自然不是連續的),堆大小受限於計算機系統中有效的虛擬記憶體(32bit系統理論上是4g),所以堆的空間比較靈活,比較大

3 碎片問題:對於棧,它是乙個先進後出的佇列,進出一一對應,不會產生碎片。對於堆,頻繁的new/delete會造成大量碎片,使程式效率降低 4

4 生長方向:棧向下,向低位址方向增長。堆向上,向高位址方向增長。 5

5 分配方式:棧有靜態分配和動態分配,靜態分配由編譯器完成(如區域性變數分配),動態分配由alloca函式分配,但棧的動態分配的資源由編譯器進行釋放,無需程式設計師實現。堆都是動態分配(沒有靜態分配的堆)

6 分配效率:棧的效率比堆高很多。棧是機器系統提供的資料結構,計算機在底層提供棧的支援,分配專門的暫存器來存放棧的位址,壓棧出棧都有相應的指令,因此比較快。堆是由庫函式提供的,機制很複雜,庫函式會按照一定的演算法進行搜尋記憶體,因此比較慢。

7 記憶體管理機制:只要棧的剩餘空間大於所申請空間,系統為程式提供記憶體,否則報異常提示棧出。系統有乙個記錄空閒記憶體位址的鍊錶,當系統收到程式申請時,遍歷該鍊錶,尋找第乙個空間大於申請空間的堆結點,刪除空閒結點鍊錶中的該結點,並將該結點空間分配給程式(大多數系統會在這塊記憶體空間首位址記錄本次分配的大小,這樣delete才能正確釋放本記憶體空間,另外系統會將多餘的部分重新放入空閒鍊錶中)

靜態全域性變數、全域性變數、靜態區域性變數、區域性變數的區別

靜態全域性變數、全域性變數區別: (1)靜態全域性變數和全域性變數都屬於全域性區

(2)靜態全域性區只在本檔案中有效,別的檔案想呼叫該變數,是調不了的,而全域性變數在別的檔案中可以呼叫

(3)如果別的檔案中定義了乙個該全域性變數相同的變數名,是會出錯的。 靜態區域性變數、區域性變數的區別

(1)靜態區域性變數是屬於全域性區的,而函式內部的區域性變數屬於棧區;

(2)靜態區域性變數在該函式呼叫結束時,不會銷毀,而是隨整個程式結束而結束,但是別的函式呼叫不了該變數,區域性變數隨該函式的結束而結束;

(3)如果定義這兩個變數的時候沒有初始值時,靜態區域性變數會自動定義為0,而區域性變數就是乙個隨機值;

(4)靜態區域性變數在編譯期間只賦值一次,以後每次函式呼叫時,不在賦值,呼叫上次的函式呼叫結束時的值。區域性變數在呼叫期間,每呼叫一次,賦一次值。

c/c++動態記憶體管理malloc/new、free/delete的異同

相同:兩者都可以用來動態申請記憶體和釋放記憶體; 不同:1.

malloc/free是c/c++標準庫的函式,new/delete是c++操作符。

2. new做兩件事,一是分配記憶體,二是呼叫類的建構函式;同樣,delete會呼叫類的析構函式和釋放記憶體。而malloc和free只是分配和釋放記憶體。

3、new建立的是乙個物件,而malloc分配的是一塊記憶體;new建立的物件可以用成員函式訪問,不要直接訪問它的位址空間;malloc分配的是一塊記憶體區域,用指標訪問,可以在裡面移動指標;

4. 返回物件,new返回的是物件型別的指標,而malloc返回的是void指標。 5、new/delete是保留字,不需要標頭檔案支援;malloc/free需要標頭檔案庫函式支援。

6. 定製記憶體大小不同,malloc/free需要手動計算型別大小,而new/delete編譯器可以自己計算型別大小。

7. 記憶體分配失敗時的返回值:new記憶體分配失敗時會直接拋bac_alloc異常, 它不會返null, malloc分配記憶體失敗時返回null。

c++的成員變數是在堆還是棧區

如果物件是函式內的非靜態區域性變數,則物件,物件的成員變數儲存在棧區。

如果物件是全域性變數,則物件,物件的成員變數儲存在靜態區。

如果物件是函式內的靜態區域性變數,則物件,物件的成員變數儲存在靜態區。

如果物件是new出來的,則物件,物件的成員變數儲存在堆區。

函式的呼叫與堆疊,例子

c++的成員變數是在堆還是棧區 如果物件是函式內的非靜態區域性變數,則物件,物件的成員變數儲存在棧區。

如果物件是全域性變數,則物件,物件的成員變數儲存在靜態區。 如果物件是函式內的靜態區域性變數,則物件,物件的成員變數儲存在靜態區。

如果物件是new出來的,則物件,物件的成員變數儲存在堆區。

C 堆疊以及記憶體分配

乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事,分配方式倒是類...

C 堆 棧和記憶體洩露

自動儲存 靜態儲存和動態儲存的區別 棧自動儲存的變數通常儲存在棧中,後進先出。堆使用new建立的記憶體空間通常被稱為自由儲存空間或堆,管理了乙個記憶體池,該記憶體池與用於靜態變數和自動變數的記憶體是分開的。記憶體洩露如果使用new運算子在自由儲存空間 或堆 上建立變數後,沒有呼叫delete,將會發...

C 堆 棧與記憶體管理

一 所謂stack和heap 例子 class complex 作用域 scope stack 儲存區域性變數或臨時物件的一塊記憶體,函式呼叫結束會消失 heap 存放全域性物件或變數的記憶體空間,函式呼叫結束如果不通過delete 釋放將直到程式執行結束之前一直存在。二 static local ...