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

C++ 記憶體越界問題與 weak_ptr 解決方案

     編輯:關於C++

懸空指標導致的記憶體越界:使用 Boost weak_ptr 自動偵測物件存活

記憶體洩漏可用工具偵測,但記憶體越界 (Use-after-free) 極難重現除錯。核心問題:指標指向的物件已被銷毀,指標本身未置空,後續存取導致未定義行為。

問題場景

Object* ptr = new Object();
// ... 某處 delete ptr ...
ptr->doSomething();  // 崩潰或無聲資料損毀

解決方案:weak_ptr 觀察者模式

利用 shared_ptr 管理物件生命週期,weak_ptr 觀察而不擁有。物件銷毀時,所有 weak_ptr 自動失效。

實作範例:可被弱引用的類別

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>

inline void null_deleter(void const*) {}  // 無操作刪除器

class X {
    boost::shared_ptr<X> this_;  // 持有自己 (配合 null_deleter)
    int i_;
public:
    explicit X(int i) : this_(this, &null_deleter), i_(i) {}
    X(const X& rhs) : this_(this, &null_deleter), i_(rhs.i_) {}
    X& operator=(const X& rhs) { i_ = rhs.i_; return *this; }

    boost::weak_ptr<X> weak_this() const { return this_; }
    void do_something() { /* ... */ }
};

使用方式

X x(42);
boost::weak_ptr<X> wp = x.weak_this();  // 取得弱引用

// 安全存取模式
if (boost::shared_ptr<X> safe = wp.lock()) {  // 升級為強引用
    safe->do_something();  // 保證物件存活
} else {
    // 物件已銷毀
}

適用範圍與限制

場景適用性說明
單執行緒、棧上物件✅ 完美weak_this() 綁定 this,物件銷毀自動失效
多執行緒共享物件⚠️ 需改用 shared_ptrweak_ptr 無法防止其他執行緒刪除物件
堆上物件 (new/delete)⚠️ 需 shared_ptr 管理手動 delete 繞過 shared_ptr 參考計數

多執行緒正確做法

// 物件由 shared_ptr 管理
boost::shared_ptr<X> sp = boost::make_shared<X>(42);
boost::weak_ptr<X> wp = sp;

// 執行緒 A
if (auto safe = wp.lock()) { safe->do_something(); }

// 執行緒 B (安全刪除)
sp.reset();  // 最後一個 shared_ptr 釋放時才真正刪除物件

核心觀念

  • shared_ptr:擁有權,參考計數控制生命週期
  • weak_ptr:觀察權,不增加計數,lock() 暫時取得擁有權
  • 單執行緒棧上物件可用 null_deleter 技巧配合 weak_ptr
  • 多執行緒或堆上物件必須用 shared_ptr 統一管理
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved