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

C++ 類對象中動態內存的釋放與重新分配:避免 Double Free 錯誤

     編輯:程式設計綜合問答

核心結論

完全可以在對象生命週期中多次 delete 並 new 重新分配內存,前提是嚴格遵循「誰分配、誰釋放、指針置空」原則,並在拷貝構造/賦值運算符中正確實現深拷貝或禁用拷貝。

案例分析:Matrix 類賦值運算符導致 Double Free

Matrix& Matrix::operator=(const Matrix &mp) {
    if (this == &mp) return *this; // 1. 自賦值檢查 必須!

    if (mp.row_n != row_n || mp.column_n != column_n) {
        // 2. 釋放舊資源
        for (int i = 0; i < row_n; ++i) delete[] element[i];
        delete[] element;

        // 3. 分配新資源
        row_n = mp.row_n; column_n = mp.column_n;
        element = new int*[row_n];
        for (int i = 0; i < row_n; ++i) element[i] = new int[column_n];
    }
    // 4. 拷貝數據
    for (int i = 0; i < row_n; ++i)
        for (int j = 0; j < column_n; ++j)
            element[i][j] = mp.element[i][j];
    return *this;
}

原代碼錯誤點

  • 註釋掉的釋放邏輯中 column_n 未更新即用於分配內層數組,導致越界/內存破壞。
  • 缺少自賦值檢查,若 a = a 會先釋放內存再讀取已釋放內存拷貝,必現 Double Free。
  • 析構函數中未將 element 置 nullptr,多次析構風險。

現代 C++ 最佳實踐 (C++11/14/17)

棄用裸指針手動管理,改用智能指針或容器:

class Matrix {
    std::vector<std::vector<int>> data_; // 自動管理內存、深拷貝、異常安全
public:
    Matrix(int r, int c) : data_(r, std::vector<int>(c)) {}
    // 編譯器自動生成的 拷貝/移動 構造/賦值/析構 均正確
    int& at(int r, int c) { return data_[r][c]; }
};

若必須手動管理(教學/嵌入式/性能極致),請嚴格實現 Rule of Five(析構、拷構、拷賦、移構、移賦)。

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