首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 淺拷貝導致 double free 錯誤:複製建構函式未深拷貝指標

     編輯:程式設計綜合問答

錯誤程式碼

class base {
public:
    base(int *a) : p(a) {}
    base(int num) : p(new int(num)) {}
    base(base& mid) : p(mid.p) { // 淺拷貝:直接複製指標值
        cout << "base is constructing!\n";
    }
    ~base() {
        if (p != NULL) {
            delete p;
            p = NULL;
        }
    }
private:
    int *p;
};

int main() {
    base one(1);   // p 指向新配置的 int(1)
    base two(one); // 淺拷貝:two.p 指向同一記憶體位址
} // two 先解構 delete p,one 再解構 delete 同一位址 → double free

錯誤原因

複製建構函式 base(base& mid) : p(mid.p) 僅複製指標值(淺拷貝),導致兩個物件擁有相同的指標 p。當物件銷毀時,析構函式各自 delete p,第二次釋放已釋放的記憶體即觸發 double free(野指標錯誤)。

正確做法:深拷貝

base(const base& mid) : p(new int(*mid.p)) { // 配置新記憶體並複製值
    cout << "base is constructing (deep copy)!\n";
}

完整規則:三大法則 / 五大法則

若類別管理動態資源(裸指標、檔案控制代碼等),必須實作:

  1. 複製建構函式
  2. 複製指派運算子 operator=
  3. 析構函式
  4. (C++11) 移動建構函式
  5. (C++11) 移動指派運算子

現代 C++ 最佳實踐

  • 優先使用智慧指標 std::unique_ptr、std::shared_ptr 管理資源,編譯器自動生成正確的移動語意,避免手動實作錯誤。
  • 若不需複製語意,刪除複製建構/指派:base(const base&) = delete;

修正後範例

#include <memory>
class base {
    std::unique_ptr<int> p;
public:
    base(int num) : p(std::make_unique<int>(num)) {}
    // 編譯器自動生成移動建構/指派,禁止複製
    base(base&&) = default;
    base& operator=(base&&) = default;
    base(const base&) = delete;
    base& operator=(const base&) = delete;
};
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved