記憶體洩漏可用工具偵測,但記憶體越界 (Use-after-free) 極難重現除錯。核心問題:指標指向的物件已被銷毀,指標本身未置空,後續存取導致未定義行為。
Object* ptr = new Object();
// ... 某處 delete ptr ...
ptr->doSomething(); // 崩潰或無聲資料損毀
利用 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_ptr | weak_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_ptrshared_ptr 統一管理