C++一些注意點之new和malloc

malloc/free和new/delete它們都可用於申請動態內存和釋放內存,但是它們卻有區別:

      (1)malloc與free是C++/C語言的內存分配標準庫函數,屬於stdlib庫;new/delete是C++的操作運算符;

      (2)new 不止是分配內存,而且會調用類的構造函數,同理delete會調用類的析構函數,而malloc則只分配內存,不會進行初始化類成員的工作,同樣free也不會調用析構函數;

例如:

  1. class Obj  
  2.   
  3. {  
  4.   
  5. public :  
  6.   
  7.           Obj(void){ cout < < “Initialization” << endl; }  
  8.   
  9. ~Obj(void){ cout < < “Destroy” << endl; }  
  10.   
  11. void      Initialize(void){ cout < < “Initialization” << endl; }  
  12.   
  13. void      Destroy(void){ cout < < “Destroy” << endl; }  
  14.   
  15. };  
  16.   
  17.    
  18.   
  19. void UseMallocFree(void)  
  20.   
  21. {  
  22.   
  23.       Obj    *a = (obj *)malloc(sizeof(obj));     // 申請動態內存  
  24.   
  25.       a->Initialize();                          // 初始化  
  26.   
  27.       //…  
  28.   
  29.       a->Destroy();     // 清除工作  
  30.   
  31.       free(a);          // 釋放內存  
  32.   
  33. }  
  34.   
  35.    
  36.   
  37. void UseNewDelete(void)  
  38.   
  39. {  
  40.   
  41.       Obj    *a = new Obj;    // 申請動態內存並且初始化  
  42.   
  43.       //…  
  44.   
  45.       delete a;             // 清除並且釋放內存  
  46.   
  47. }  
  48.   
  49. 類Obj的函數Initialize模擬了構造函數的功能,函數Destroy模擬了析構函數的功能。函數UseMallocFree中,由於malloc/free不能執行構造函數與析構函數,必須調用成員函數Initialize和Destroy 來完成初始化與清除工作。函數UseNewDelete則簡單得多。所以我們不要企圖用malloc/free來完成動態對象的內存管理,應該用new/delete。  

 

          (3)內存泄漏對於malloc或者new都可以檢查出來的,區別在於new可以指明是那個文件的那一行,而malloc沒有這些信息。

            (4)返回類型不同:函數malloc 的原型爲void * malloc(size_t size),用malloc 申請一塊長度爲length 的整數類型的內存,返回類型void類型指針(所以在使用malloc的時候你必須手動轉換爲相應的類型)。而new 返回指定類型的指針,並且可以自動計算所需要大小;

注:爲什麼free函數不象malloc函數那樣複雜呢?這是因爲指針p的類型以及它所指的內存的容量事先都是知道的,語句free(p)能正確地釋放內存。如果pNULL指針,那麼freep無論操作多少次都不會出問題。如果p不是NULL指針,那麼freep連續操作兩次就會導致程序運行錯誤。

例如:

  1. int *p;  
  2. p = new int//返回類型爲int* 類型(整數型指針),分配大小爲 sizeof(int);  
  3. 或:  
  4. int* parr;  
  5. parr = new int [100]; //返回類型爲 int* 類型(整數型指針),分配大小爲 sizeof(int) * 100;  
  6. 而 malloc 則必須由我們計算要字節數,並且在返回後強行轉換爲實際類型的指針。  
  7. int* p;  
  8. p = (int *) malloc (sizeof(int));//這裏有兩點需要注意:(1)必須自己手動轉換;(2)必須用sizeof計算空間大小  
  9. //用malloc分配連續的空間  
  10. int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100個整數的內存空間。  

       (5)newmalloc雖然都是申請內存,但申請的位置不同,new的內存從free store分配,而malloc的內存從heap分配(詳情請看ISO14882的內存管理部分),free storeheap很相似,都是動態內存,但是位置不同,這就是爲什麼new出來的內存不能通過free來釋放的原因。不過微軟編譯器並沒有很好的執行標準,很有可能把free storeheap混淆了,因此,free有時也可以;

    (6)new是類型安全的,而malloc不是。

例如:

  1. int* p = new float[2]; // 編譯時指出錯誤   
  2. int* p = malloc(2*sizeof(float)); // 編譯時無法指出錯誤   
  3. new operator 由兩步構成,分別是 operator new 和 construct   


幾個注意點:

        (1)把newdeletemallocfree混在一起用也是個壞想法。對一個用new獲取來的指針調用free,或者對一個用malloc獲取來的指針調用delete,其後果是不可預測的;

        (2)delete數組的時候忘了 “[ ]”,容易遺漏對象,造成內存泄露;

        (3)malloc申請空間時,不對空間進行檢查,造成不可預料的錯誤。

        (4)如果用new 創建對象數組,那麼只能使用對象的無參數構造函數。即沒有默認構造函數的類,不能用new來創建數組。

(5)在delete一個變量後,還要跟上賦值爲0。例:cathouse = new cat(i); delete cathouse[i]; cathouse[i]=0;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章