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

C++ 智慧指標 auto_ptr:動態記憶體管理的安全衛士

     編輯:關於C++

痛點:異常導致的記憶體洩漏

動態記憶體管理中,new/delete 配對看似簡單,但異常拋出會打斷正常控制流,導致 delete 無法執行:


void g() { if (cond) throw X(); }

void func() {
    string* pstr = new string;
    g();              // 若拋出異常
    delete pstr;      // 永不執行 → 記憶體洩漏
}

局部自動變數(棧上物件)在異常展開棧時會自動呼叫解構函數,天然安全。但鏈表、STL 容器、資料庫連線等**必須**使用動態分配。

std::auto_ptr:RAII 解決方案

C++98 標準庫引入 <memory> 中的 std::auto_ptr,以**擁有權轉移**語義管理單一動態物件生命週期。

基本用法


#include 
#include 
using namespace std;

void func() {
    auto_ptr pstr(new string); // 建構時取得擁有權
    *pstr = "hello";                   // 重載 operator* / operator->
    pstr->size();
    // 離開作用域自動 delete pstr,異常安全
}

關鍵特性

  • 構造函數為 explicit:禁止隱式轉換 auto_ptr<T> p = new T;(編譯錯誤)。
  • 重載 *、->:像原始指標一樣使用。
  • 解構函數自動 delete:棧展開時保證釋放。
  • 不可管理陣列:auto_ptr<char> p(new char[10]) 會用 delete 而非 delete[] → 未定義行為。

擁有權轉移語義:雙面刃

auto_ptr 複製/賦值會**轉移擁有權**,來源變為 null:


auto_ptr pw1(new Widget);
auto_ptr pw2(pw1);  // pw1 變 null,pw2 擁有 Widget
pw1 = pw2;                  // pw2 變 null,pw1 重獲擁有權

這違反標準複製語義,導致**嚴重缺陷**:

  • 不可放入 STL 容器:vector<auto_ptr<T>> 排序/複製時會讓元素變 null、物件被過早刪除。
  • 標準委員會**明確禁止** auto_ptr 作為容器元素。

避坑指南

  1. 絕不放入容器:需智慧指標容器請用 shared_ptr (C++11) 或 boost::shared_ptr。
  2. 絕不管理陣列:陣列請用 vector、unique_ptr<T[]> (C++11) 或 scoped_array。
  3. 單一擁有者場景適用:函數內部暫存、工廠函數返回、成員變數持有。

歷史定位與現代替代

auto_ptr 是 C++98 產物,C++11 引入 unique_ptr(移動語義、支援陣列、可放入容器)與 shared_ptr(共享擁有權)徹底取代它。C++17 標記 auto_ptr 為**棄用**,C++20 **移除**。

結語

理解 auto_ptr 的 RAII 思想與擁有權轉移缺陷,是掌握現代 C++ 智慧指標體系的關鍵基石。新代碼請直接使用 unique_ptr/shared_ptr。

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