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

C/C++ 記憶體管理實戰(四):free/delete 後的指標狀態、野指標根除、new/delete vs malloc/free

     編輯:VC 教學

7.5 free/delete 後指標怎麼了?

free(p) 或 delete p 僅釋放記憶體,**不會自動將指標設為 NULL**。指標仍保有原位址值,變成野指標。

7.7 根除「野指標」

野指標 ≠ NULL 指標,是指向「垃圾」記憶體的指標。if 可判斷 NULL,但對野指標無效,極度危險。

野指標三大成因

  1. 指標未初始化:新建指標預設值隨機,亂指一氣。創建時必須初始化:char* p = NULL; 或指向合法記憶體。
  2. free/delete 後未置 NULL:釋放記憶體後須立即 p = NULL;,否則誤以為仍合法。
  3. 指標操作超出變數作用域:最難防範。例:

class A {
public:
    void Func() { cout << "Func of A" << endl; }
};
void Test() {
    A* p;
    {
        A a;
        p = &a; // a 生命週期僅在此區塊
    }
    p->Func(); // p 成為野指標,a 已銷毀
}

執行 p->Func() 時 a 已消失,p 指向已釋放的堆疊記憶體。某些編譯器可能偶然不報錯,但屬未定義行為。

7.8 有了 malloc/free 為何還要 new/delete?

  • malloc/free:C/C++ 標準庫**函式**。
  • new/delete:C++ **運算子**。

對**非內建型別物件**,malloc/free 無法滿足需求:

  • 物件建立需自動執行**建構函式**;
  • 物件銷毀前需自動執行**解構函式**。

malloc/free 是庫函式,不在編譯器控制權下,無法強制執行建構/解構。因此 C++ 需要 new(配置+初始化)與 delete(清理+釋放)。

對比範例


class Obj {
public:
    Obj() { cout << "Initialization" << endl; }
    ~Obj() { cout << "Destroy" << endl; }
    void Initialize() { cout << "Initialization" << endl; }
    void Destroy() { cout << "Destroy" << endl; }
};

void UseMallocFree() {
    Obj* a = (Obj*)malloc(sizeof(Obj)); // 僅配置記憶體
    a->Initialize();                    // 手動初始化
    // ...
    a->Destroy();                       // 手動清理
    free(a);                            // 釋放記憶體
}

void UseNewDelete() {
    Obj* a = new Obj; // 配置 + 自動建構
    // ...
    delete a;         // 自動解構 + 釋放
}

UseNewDelete 簡潔得多。動態物件必須用 new/delete;內建型別兩者等價。

為何不淘汰 malloc/free?

C++ 常呼叫 C 函式,C 只能用 malloc/free 管理動態記憶體。兩套機制須共存。

配對使用鐵律

  • new 配 delete,malloc 配 free。
  • free 釋放 new 物件 → 無法執行解構函式 → 錯誤。
  • delete 釋放 malloc 記憶體 → 理論不錯但可讀性極差。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved