首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C++ delete 運算子與函數全解析:正確釋放記憶體、避免洩漏與未定義行為

     編輯:關於C語言

兩種 delete 的本質區別

特性delete 運算子operator delete 函式
語法形式delete ptr; / delete[] arr;void operator delete(void* ptr) noexcept;
自動呼叫解構函式是否
可否重載不可(內建)可(全域/類別成員)
對應 newnew 運算子operator new 函式

delete 運算子執行流程

// delete ps;  其中 ps: string*
ps->~string();           // 1. 呼叫解構函式
operator delete(ps);     // 2. 釋放原始記憶體

陣列形式 delete[] arr; 會依序呼叫每個元素解構函式,再釋放整塊記憶體。

operator delete 重載場景

全域取代

void* operator new(size_t sz) {
    void* p = malloc(sz);
    if (!p) throw std::bad_alloc();
    return p;
}
void operator delete(void* p) noexcept { free(p); }

類別專屬(含陣列版)

class Widget {
public:
    static void* operator new(size_t sz) { return pool_.alloc(sz); }
    static void operator delete(void* p) noexcept { pool_.free(p); }
    static void* operator new[](size_t sz) { return pool_.alloc(sz); }
    static void operator delete[](void* p) noexcept { pool_.free(p); }
private:
    static MemoryPool pool_;
};

Placement New 對應的釋放規則

char buffer[sizeof(Widget)];
Widget* pw = new (buffer) Widget();  // Placement new

// 正確釋放順序
pw->~Widget();          // 顯式呼叫解構函式
// 禁止:delete pw;     // 錯誤!buffer 不在堆積上
// 禁止:operator delete(pw); // 錯誤!同上

Placement new 僅在既有記憶體建構物件,不配置記憶體,故無對應 delete 運算子。

六大核心法則

  1. 配置與釋放成對:new 對應 delete,new[] 對應 delete[],malloc 對應 free,placement new 對應顯式解構
  2. 型別必須匹配:以 Base* 刪除 Derived 物件需虛解構函式
  3. 釋放後置空:delete p; p = nullptr; 防止雙重釋放與懸空指標
  4. 釋放 nullptr 安全:標準保證 delete nullptr 無副作用
  5. 陣列與標量不可混用:new T[10] 必須 delete[],否則未定義行為
  6. 自訂配置器需成對重載:重載 operator new 必須重載對應 operator delete

常見錯誤與偵錯技巧

錯誤模式後果偵測工具
未釋放記憶體洩漏Valgrind, AddressSanitizer, VS CRT Debug Heap
雙重釋放堆積損毀、崩潰同上 + _CrtSetDbgFlag
使用已釋放記憶體未定義行為、資料竊取ASan, PageHeap
錯誤 delete[]解構函式漏呼/多呼程式碼審查、靜態分析

現代 C++ 最佳實踐

  • 優先使用 std::unique_ptr、std::shared_ptr、std::vector 等 RAII 容器
  • 自訂刪除器:std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(...), fclose);
  • 避免裸指標擁有權,new/delete 封裝在建構/解構函式內

徹底理解 delete 的雙重身分與執行語意,是寫出無洩漏、無 UB、高效能 C++ 程式的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved