new/delete和malloc/free都是用于在C++(以及C語言在malloc/free的情況下)中動態申請和釋放內存的機制,但它們之間存在一些顯著的異同點。以下是對這兩組函數/運算符的異同點的詳細分析:
相同點
- 目的相同:兩者都用于在堆(heap)上動態地分配和釋放內存。
- 手動管理:無論是new/delete還是malloc/free,都需要程序員手動進行內存的分配和釋放,以避免內存泄漏。
不同點
- 類型與來源
new/delete:是C++的運算符,支持重載,可以與C++的類特性(如構造函數、析構函數)緊密集成。
malloc/free:是C語言(及C++兼容)的標準庫函數,分別定義在<stdlib.h>(C語言)和(C++)頭文件中。 - 內存分配與初始化
new:能夠自動根據對象的類型計算所需內存大小,并在分配內存后自動調用對象的構造函數進行初始化(如果是類類型的對象)。
malloc:需要程序員手動計算所需內存大小,并且分配的內存不會自動初始化,通常包含未定義的值。 - 返回值
new:返回指向分配的內存的指針,該指針的類型是所分配對象的類型。
malloc:返回void*類型的指針,指向分配的內存,需要程序員根據需要進行類型轉換。 - 錯誤處理
new:如果內存分配失敗,會拋出std::bad_alloc異常。
malloc:如果內存分配失敗,會返回NULL(在C++11及以后,推薦使用nullptr)。 - 內存釋放
delete:在釋放內存時,會調用對象的析構函數(如果是類類型的對象),然后釋放內存。
free:僅釋放之前通過malloc分配的內存,不會調用任何析構函數。 - 數組支持
new/delete:對于數組,有專門的語法new 類型[大小]和delete[] 指針來分配和釋放內存。
malloc/free:對于數組,只需在malloc中指定數組總大小(每個元素的類型大小乘以元素數量),并在free中傳遞指向數組首元素的指針。但注意,malloc不會自動處理數組元素的構造或析構。 - 類型安全
new:提供了更好的類型安全,因為返回的是具體類型的指針,編譯器可以進行類型檢查。
malloc:由于返回void*類型,需要程序員進行類型轉換,這可能引入類型錯誤。 - 性能
在底層實現上,new/delete通常是對malloc/free的封裝,因此它們的性能差異主要取決于封裝層的開銷。在大多數情況下,這種差異可以忽略不計,但在性能敏感的應用中可能需要考慮。
現在開始添加阿秀總結部分(很清晰、易懂,非常建議學習
-
new是類型安全的,malloc不是。例如:
int*p=newfloat[2];//編譯錯誤 int *p = (int*)malloc(2*sizeof(double));//編譯無錯誤
-
new調用名為operator new的標準庫函數分配足夠空間并調用相關對象的構構造函數,delete對指針所指對象運行適當的析構函數,然后通過調用名為perator delete的標準庫函數釋放該對象所用內存。后者均沒有相關調用。
-
new是封裝了malloc,直接free不會報錯,但是這只是釋放內存,而不會析構對象
-
new和delete是如何實現的?
new的實現過程是:首先調用名為operator new的標準庫函數,分配足夠大的原始為類型化的內存,以保存指定類型的一個對象;接下來運行該類型的一個構造函數,用指定初始化構造對象;最后返回指向新分配并構造后的的對象的指針;
delete的實現過程:對指針指向的對象運行適當的析構函數;然后通過調用名為operator delete的標準庫函數釋放該對象所用內存; -
malloc和new的區別?
malloc和free是標準庫函數,支持覆蓋;new和delete是運算符,支持重載。
malloc僅僅分配內存空間,free僅僅回收空間,不具備調用構造函數和析構函數功能,用malloc分配空間存儲類的對象存在風險;new和delete除了分配回收功能外,還會調用構造函數和析構函數。
malloc和free返回的是void類型指針(必須進行類型轉換),new和delete返回的是具體類型指針。 -
既然有了malloc/free,C++中為什么還需要new/delete呢?直接用malloc/free不好嗎?
malloc/free和new/delete都是用來申請內存和回收內存的。
在對非基本數據類型的對象使用的時候,對象創建的時候還需要執行構造函數,銷毀的時候要執行析構函數。而malloc/free是庫函數,是已經編譯的代碼,所以不能把構造函數和析構函數的功能強加給malloc/free,所以new/delete是必不不可少的。 -
被free回收的內存是立即返還給操作系統嗎?
不是的,被free回收的內存會首先被ptmalloc使用雙鏈表保存起來,當用戶下一次申請內存的時候,會嘗試從這些內存中尋找合適的返回。這樣就避免了頻繁的系統調用,占用過多的系統資源。同時ptmalloc也會嘗試對小塊內存進行合并,避免過多的內存碎片。
總結
new/delete和malloc/free各有其適用場景。在C++程序中,由于new/delete能夠與C++的類特性更好地集成,因此通常是首選的內存分配方式。然而,在處理與C語言的接口或需要更低級內存操作的情況下,malloc/free仍然有其不可替代的作用。重要的是,無論使用哪種方式,都應確保及時釋放分配的內存,以避免內存泄漏。