雖然 new/delete 與 malloc/free 都能動態分配/釋放記憶體,但它們屬於完全不同的語言層級,混用會導致嚴重錯誤。
| 維度 | new / delete | malloc / free |
|---|---|---|
| 性質 | C++ 運算子(可重載) | C 標準庫函式 |
| 頭文件 | 無需(關鍵字) | <cstdlib> / <stdlib.h> |
| 建構/解構 | 自動呼叫 | 不呼叫(僅原始記憶體) |
| 型別安全 | 回傳具型別指標 | 回傳 void* 需強制轉型 |
| 失敗處理 | 拋出 std::bad_alloc | 返回 NULL |
| 陣列支援 | new T[n]/delete[] | 手動計算 n * sizeof(T) |
| 自定義分配 | 運算子重載、placement new | 自訂分配器函式 |
非 POD 型別(含建構/解構函數的類別)必須在記憶體上執行建構/解構邏輯。malloc 只是原始位元組塊,編譯器無法注入建構/解構呼叫。new 內部封裝:
T* p = static_cast<T*>(operator new(sizeof(T))); // 分配
new (p) T(args...); // placement new 呼叫建構函數
delete 對稱:呼叫解構函數 → operator delete(p) 釋放記憶體。
malloc 分配 → delete 釋放:不呼叫解構函數,釋放函數簽名不匹配(operator delete vs free),堆損壞。new 分配 → free 釋放:不呼叫解構函數,同樣導致堆損壞。new T[n] → free / delete(非陣列版):解構次數錯誤、Cookie 損壞。鐵律:new 配 delete,new[] 配 delete[],malloc 配 free,三組不可交叉。
new/delete 或智慧指標/容器。xmlFree、sqlite3_free)。std::unique_ptr<T, Deleter> 自定義刪除器。malloc/free,C++ 端用 placement new 建構物件,釋放前手動呼叫解構函數再 free。new/delete:用 std::make_unique、std::make_shared、std::vector、std::string。operator new/delete 或提供 std::pmr::memory_resource(C++17)。
new/delete是 C++ 型別系統的一部分,語意包含「分配+建構」與「解構+釋放」;
malloc/free是 C 原始記憶體操作,無型別、無語意。
現代 C++ 開發者應將 malloc/free 視為「底層基礎設施」,僅在與 C 互操作或實作分配器時接觸。