C 之記憶體管理

2021-08-20 20:00:17 字數 3232 閱讀 3472

malloc

calloc

realloc

上述三種方式是使用者在堆上開闢空間的辦法,用完後必須用free釋放,否則會造成記憶體洩露。

值得一提的是實際開闢的記憶體比申請的空間大:前面多申請32個位元組,後面多申請4個位元組。具體原因這裡就不再闡述,詳情見c語言動態分配記憶體

c語言記憶體管理方式在c++中可以繼續使用,同時c++又提出了自己的內

存管理方式:c++中通過new和delete運算子進行動態記憶體管理。

new和delete、new和delete一定匹配使用

1. new 申請記憶體

new的用法:

new 資料型別 ;                  //申請記憶體空間。

new 資料型別 (初值); //申請記憶體空間時,並指定該資料型別的初值。

new 資料型別 [記憶體單元個數]; //申請多個記憶體空間。

new的樣例:

int *p1 = new

int; //申請乙個大小為int的空間給p1

int *p2 = new

int(2); //申請乙個大小為int的空間給p2,並且初始化為2

int *p3 = new

int[3]; //開闢乙個大小為3個整型的連續空間給p3

原始碼剖析:

在除錯過程中檢視原始碼:

// new int

void *__crtdecl operator

new(size_t size) _throw1(_std bad_alloc)

return (p);

}// new int(3)

void *__crtdecl operator

new(size_t size) _throw1(_std bad_alloc)

return (p);

}// new int[3]

void *__crtdecl operator

new(size_t count) _throw1(std::bad_alloc)

可以看到,無論是哪種方式使用new來申請空間,實際上都是呼叫malloc函式。如果呼叫malloc函式申請空間失敗,就會呼叫_callnewh(size)在堆上做出處理,然後繼續嘗試malloc。如果做處理時失敗,就會丟擲異常。

因此,使用new來開闢空間時,也就不需要使用者判斷是否成功開闢了空間。如果呼叫new返回位址了,那麼這段位址的空間一定是能用的;如果開闢空間失敗,則會直接報錯。

對於類:

new做的事:

1.呼叫operator new分配空間

2.呼叫建構函式初始化空間

new[n]做的事:

1.呼叫operator new分配空間

2.呼叫n次建構函式分別初始化每個物件

2. delete 釋放記憶體

detele的用法:

detete 變數名; //釋放單個資料型別記憶體

delete 變數名; //釋放陣列空間

detele的使用樣例:

delete p1;  //釋放p1

delete p2; //釋放p2

delete p3; //釋放連續陣列空間

原始碼剖析:

c中的free:

extern

"c" _crtimp void __cdecl free(

void * puserdata

)

c++中delete:

// delete p1

void

operator

delete(

void *puserdata

)// delete p2

void

operator

delete(

void *puserdata

)//delete p3

void

operator

delete( void * p )

同樣,可以看到delete實際上就是對free函式做了封裝。delete p;只是釋放*p中的內容,而不改變指標p本身,p存放的依然是申請空間時的位址。

對於類:

delete做的事:

1.呼叫析構函式清理物件

2.呼叫operator delete釋放空間

delete 做的事:

1.呼叫n次析構函式清理物件

2.呼叫operator delete釋放空間

3. 定位new表示式

定位new表示式是在已分配的原始記憶體空間中呼叫建構函式初始化乙個物件,此不再從堆中申請新的記憶體。

//例子:

char * buffer = new

char [500];

testdata *data1 = new (buffer) testdata; //在new上已有記憶體上構建物件

testdata *data2 = new (data1 + 1) testdata; //再次利用new在data1

//之後構建第二個testdata物件

定位new不同與常規的new運算子,定位new運算子不需要相應的delete運算子來釋放記憶體。因為它本身就不開闢新的記憶體。

簡單來說就是new運算子只是返回傳遞給它的位址,並將其強制轉換為void *,以便能夠賦給任何指標型別。

用將定位new運算子來建立新的類物件後,當該物件消亡時,程式並不會自動地呼叫其析構函式,所以必須顯示地呼叫析構函式。這個少數的需要顯示呼叫析構函式的情況之一。

對於使用定位new運算子建立的物件,應以與建立順序相反的順序進行刪除。原因在於,晚建立的物件可能依賴於早建立的物件。另外,僅當所有物件都被銷毀後,才能釋放用於儲存這些物件的緩衝區。

c 之記憶體管理

c 使用3 種不同解決方案儲存資料,區別是資料保留在記憶體中的時間 兩種儲存持續性為自動 自動變數和暫存器變數 register 沒有記憶體位址 堆疊 在函式外定義的變數和使用關鍵字static定義的變數的儲存持續性都為靜態.分為 3 外部鏈結性,內部鏈結性和無鏈結性 所有靜態變數都有下面的兩個初始...

C 之記憶體管理介紹

申請記憶體,使用運算子 new 釋放記憶體,使用運算子 delete 申請記憶體 int p new int 釋放記憶體 delete p.申請乙個塊記憶體 int arr new int 10 釋放塊記憶體 delete arr 判斷申請記憶體是否失敗 if null p 則說明記憶體分配失敗了,...

c基礎之記憶體管理

一 作用域 全域性變數和區域性變數 靜態全域性和區域性變數 總結 型別作用域 生命週期 區域性變數 int a 10 從變數定義到函式結束 區域性變數建立到函式結束 全域性變數 int a 10 整個專案檔案 程式建立到程式結束 static 區域性變數 int a 10 從變數定義到函式結束 程式...