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會出錯