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

C++ 運算符重載中內存釋放與深拷貝的必要性

     編輯:程式設計疑難解答

問題代碼

MyString& MyString::operator=(const MyString& str) {
    if (this == &str) return *this;
    delete[] m_pData;          // 為什麼要釋放?
    m_pData = NULL;
    m_pData = new char[strlen(str.m_pData) + 1];
    strcpy(m_pData, str.m_pData);
    return *this;
}

兩大核心問題

1. 不 delete 會導致內存洩漏

若直接賦值 m_pData = str.m_pData,原 m_pData 指向的內存塊失去引用,無法被釋放,造成內存洩漏。長期運行程序會耗盡堆內存。

2. 直接賦值指針導致淺拷貝錯誤

若執行 m_pData = str.m_pData,兩對象共享同一內存塊:

MyString s1("hello"), s2("world");
s1 = s2; // 淺拷貝後 s1.m_pData == s2.m_pData
s2.m_pData[0] = 'W'; // 修改 s2 導致 s1 內容也變為 "World"

這違背了賦值語義:s1 = s2 後修改 s2 不應影響 s1(類似 int a=b; b=3; a 仍為原值)。

正確實現模式:複製-交換惯用法

MyString& MyString::operator=(MyString other) { // 參數傳值觸發拷貝構造
    swap(*this, other); // 交換內部指針
    return *this;       // other 析構時釋放舊內存
}

void swap(MyString& a, MyString& b) noexcept {
    std::swap(a.m_pData, b.m_pData);
}

關鍵點總結

  • 自賦值檢查:if (this == &str)
  • 釋放舊資源:delete[] m_pData
  • 分配新內存:new char[len+1]
  • 深拷貝數據:strcpy
  • 返回 *this 支持鏈式賦值
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved