C++程序設計基礎(6)內存分配

1.知識點

三步走:申請,釋放,指針置空。面試

1.1malloc、free函數

在C語言中內存malloc函數申請動態空間,如下展現其基本用法:數組

1 int *p = NULL; 2 p = (int *)malloc(sizeof(int) * 10);//申請
3 free(p);//釋放,不然會形成內存泄漏
4 p = NULL;//指針置空,不然成爲野指針

(1)動態分配的空間來自隊空間,而指針自己做爲局部變量存儲在棧空間中。函數

(2)malloc有時候也可能申請空間失敗,這時返回NULL,故須要對其進行判斷。spa

(3)經過malloc動態申請的空間必須經過free函數釋放,這兩個函數成對出現。不然可用空間會愈來愈少。指針

(4)在經過free函數釋放以後,最好將指針置空。code

(5)malloc/free函數申請釋放的過程其實就是可用空間鏈表不斷在更新。對象

1.2new、delete函數

(1)new和delete運算符既能夠應用於基本類型,也能夠用於自定義類型,new操做符不只申請了空間,而後還根據提供的參數進行構造函數初始化,delete在釋放內存空間以前還會調用對象的析構函數,這些事new/delete比malloc/free更爲豐富的地方。blog

2.面試題

2.1malloc和free的常識性問題

如下說法正確的是(D)。內存

(A)free會將指針置爲空    //須要手動置空table

(B)malloc函數的返回指針移動後,free函數會自動找到首地址並釋放     //不能失去對首地址的控制,不然沒法釋放

(C)malloc函數一次申請N個int空間,使用後須要循環N次逐一調用free釋放  //malloc和free成對出現

(D)malloc申請的空間位於堆上

2.2返回一個64整數倍的地址

編寫兩個函數,align64malloc和align64free,分別用於申請空間和釋放空間,並要求申請空間返回的地址必須是64的整數倍。

解析:在所需空間前面再加上64個字節,可保證其中確定有一個地址是64的倍數,再在這64個字節空間的前面再加上4個字節保證有地方能夠存儲返回的首地址。以下表所示

A 4個字節
B 64個 字節
C N個字節
 1 void * align64malloc(int size) {  2     void *ptr = malloc(sizeof(int)*size + 64 + sizeof(void *));  3     if (!ptr) {  4         return NULL;  5  }  6     ptr = (char *)(ptr)+sizeof(void *);    //在最前面預留出來了存放首地址的存儲空間  7     //接下來一步須要將首地址空間放入到64整數倍前面的空間中去
 8     *((int *)(((int)ptr+64-(int)ptr%64)-sizeof(void *)))=(int)ptr - sizeof(void *);//等式右邊爲首地址,void*是不能夠進行加減運算
 9     return  (void *)((int)ptr + 64 - (int)ptr % 64); 10 } 11 
12 void algin64free(void * ptr) { 13     if (ptr) { 14         free((void *)(*((void **)ptr - 1)));//void *不能進行加減,轉換成指針的指針以後能夠進行加減 15  } 16 }

2.3簡述malloc/free和new/delete的區別

(1)malloc/free是C語言提供的庫函數,經過函數調用訪問,須要傳遞參數並接收返回值;而new/delete是C++提供的操做符,有本身的一套語法規則和運算方式。

(2)malloc/free只能用於基本的數據類型,而new/delete不但能用於基本數據類型,還能夠用於面向對象中的自定義類型。

(3)malloc函數返回的是void*類型,程序須要顯示的轉換成所須要的指針類型,new操做符後面直接指明瞭類型,不涉及類型轉換問題。

(4)malloc只負責申請空間,並返回首地址;new運算符除了申請空間,還會調用構造函數初始化指針指向的內容;free韓式只負責 釋放空間,並標識這段空間爲可用空間;delete運算符除了釋放空間,還會調用對象的析構函數。

(5)事實上,後者覆蓋了前者的所有功能,之因此在C++中還保留malloc/free函數,主要是爲了解決兼容性問題,防止C++中調用包含malloc/free的C函數時出現錯誤。

2.4簡述delete和delete[]的區別

答案(1)當new[]中數組的元素是基本類型時,經過delete和delete[]均可以釋放數組空間;

(2)當new[]中的數組元素是自定義的類型時,只能經過delete[]釋放數組空間(由於用delete只調用第一個元素的析構函數)。

強烈建議申請和釋放空間是採用徹底配對的方式:new和delete成對使用,new[]和delete[]成對使用。

如下兩個例子說明:

1 //基本類型時兩者均可以 2 //A
3 int *i = new int[5]; 4 delete i; 5 //B
6 int *i = new int[5]; 7 delete[] i;
 1 //自定義類型new[]/delete[]必須成對
 2 class Test {  3 private:  4     char *text;  5 public:  6     Test(int lenght = 100) {  7         text = new char[lenght];  8  }  9     ~Test() { 10         delete text; 11         cout << "A destructor" << endl; 12  } 13 }; 14 
15 Test *a = new Test[5]; 16 delete[] a;//使用delete會出錯
相關文章
相關標籤/搜索