一、new、delete、malloc、free1.new、delete、malloc、free關係delete會調用對象的解構函式,和new對應free只會釋放記憶體,new調用建構函式。malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算子。它們都可用於申請動態記憶體和釋放記憶體。對於非內部資料類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在建立的同時要自動執行建構函式,對象在消亡之前要自動執行解構函式。由於malloc/free是庫函數而不是運算子,不在編譯器控制許可權之內,不能夠把執行建構函式和解構函式的任務強加於malloc/free。因此C++語言需要一個能完成動態記憶體分配和初始化工作的運算子new,以及一個能完成清理與釋放記憶體工作的運算子delete。注意new/delete不是庫函數。
2.delete與 delete []區別delete只會調用一次解構函式,而delete[]會調用每一個成員的解構函式。在More Effective C++中有更為詳細的解釋:“當delete操作符用於數組時,它為每個數組元素調用解構函式,然後調用operatordelete來釋放記憶體。”delete與New配套,delete []與new []配套
MemTest *mTest1 = new MemTest[10];
MemTest *mTest2 = new MemTest;
int *pInt1 = new int[10];
int *pInt2 = new int;
delete []pInt1; //-1-
delete []pInt2; //-2-
delete []mTest1;//-3-
delete []mTest2;//-4-
在-4-處報錯。
這就說明:對於內建單一資料型別,delete和delete[]功能是相同的。對於自訂的複雜資料類型,delete和delete[]不能互用。delete[]刪除一個數組,delete刪除一個指標簡單來說,用new分配的記憶體用delete刪除用new[]分配的記憶體用delete[]刪除delete[]會調用數組元素的解構函式。內部資料類型沒有解構函式,所以問題不大。如果你在用delete時沒用括弧,delete就會認為指向的是單個對象,否則,它就會認為指向的是一個數組。
3.CSDN論壇:new可以看成兩個動作:1。分配記憶體(相當於malloc)2。引發建構函式。4.百度上回答:1,malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算子。它們都可用於申請動態記憶體和釋放記憶體。2, 對於非內部資料類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在建立的同時要自動執行建構函式,對象在消亡之前要自動執行解構函式。由於malloc/free是庫函數而不是運算子,不在編譯器控制許可權之內,不能夠把執行建構函式和解構函式的任務強加於malloc/free。3,因此C++語言需要一個能完成動態記憶體分配和初始化工作的運算子new,以一個能完成清理與釋放記憶體工作的運算子delete。注意new/delete不是庫函數。4,C++程式經常要調用C函數,而C程式只能用malloc/free管理動態記憶體new 是個操作符,和什麼"+","-","="...有一樣的地位簡單的說:malloc,free是c的函數,new,delete是c++的運算子此外,new是強制類型的,malloc不是,需要類型轉換當然還有很多不同 new 可以調用建構函式在聲明的時候初始化malloc只是分配空間,需要在其他地方初始化而delete不僅會釋放空間,在釋放前會調用解構函式而且malloc需要指定分配空間大小, 而new是自動計算的
5.實驗
通過關鍵字new分配的內在必須由開發人員自己去釋放。一塊內在如果沒有釋放,則可以一直存在到該應用程式結束。在c++中,使用delete來釋放記憶體。
分配單個記憶體文法:
類型標識符 *指標名 = new 類型標識符(初始值);//如:int *p = new int(10);
對於數組分配記憶體文法:
類型標識符 *指標名 = new 類型標識符 [數組長度];//如:int *p= new int[10];
對於單個記憶體釋放文法為:
delete 指標名;
對於數組,釋放文法為:
delete []指標名;//注意[]在指標名之前
#include<iostream>using namespace std;int main(){ int *p= new int; cout<<"輸入數組長度:"<<endl; cin>>*p; cout<<"請輸入數組的元素:"<<endl; int *q=new int[*p];// 對於數組, 用 new 資料類型[數組長度]; for(int i=0;i<*p;i++) cin>>q[i]; /* 這裡是q[i],而不是*q[i]. 相當於: int a[10]={1,2,3,4,5,6,7,8,9,0}; int *q;//int *q=a; q=a; 所以q[i]==a[i]; */ cout<<"數組元素為:"<<endl; for(int i=0;i<*p;i++) cout<<q[i]<<'\t'; cout<<endl; delete p;//delete單個記憶體 delete []q;//注意這裡[]在指標名前 system("pause"); }
結果:
二、malloc和memset
在C中 malloc和memset是2個常用的對記憶體操作的函數。首先還是來看一下這2個函數的函數原型。
1.malloc函數malloc函數用於從堆上分配指定位元組的記憶體空間。void * malloc(size_t n);
其中,形參n為要求分配的記憶體位元組數。如果執行成功,函數範圍獲得的記憶體空間的首地址;執行失敗,傳回值為NULL。由於函數傳回值值的類型為void的指標,因此,可以將void指標類型轉換後賦值給任意類型指標,這樣就可以通過操作該類型指標來操作從堆上獲得的記憶體空間。需要注意的是malloc函數分配得到的記憶體空間是未初始化的。有時候,在使用前需要對該記憶體空間進行初始化,memset就派上用場了。2.memset函數
void * memset (void * p,int c,size_t n);
其中,指標p為所操作的記憶體空間的首地址,c為每個位元組所賦的值,n為所操作記憶體空間的位元組長度,也就是記憶體被賦值為c的位元組數。在使用memset時經常要注意的它是以位元組為單位進行賦值的,所賦值的範圍是0x00~0xFF。若想要對一個double或int型的數組賦值時,就特別需要注意這一點:example1:char a[4];memset(a, '\0', 4);
example2:int a[4];memset(a, 1, 4);//這裡改成memset(a,1,5*sizeof(int))也是不可以的第一個例子是正確的,memset對字元數組裡的每個char類型元素賦值為NULL。第二個例子顯然得到的結果不是把int型數組裡的每個元素賦值為了1。因為memset函數以位元組為單位進行賦值,那麼數組中一個int型元素的4個位元組都將被賦值為1(或者說ASCII碼1所對應的字元),實際上它所表示的整數是0x01010101。另外,在使用malloc為一個二維數組分配記憶體空間時,要特別注意使用memset進行初始化可能會出錯。
int m = 2;
int n = 3;
int i;
//二位元組a[m][n]
int **a;
a = (int **) malloc(m * sizeof(int *));
for(i=0; i<m; ++i)
{
a[i] = (int *) malloc(n * sizeof(int));
}
memset(a, 0, sizeof(int) * m * n);對所有二維以上的數組使用memset時,若此多維陣列是通過多次調用malloc函數搭積木分配得到的,那麼該數組的記憶體空間可能不連續。使用memset函數進行連續的統一賦值就毫無意義了。直接聲明的多維陣列如a[2][3]的記憶體空間顯然是連續的,此時使用memset函數初始化就沒有問題。