[英]Getting raw ptr from a shared_ptr and make it shared again
為什么下面的代碼不起作用?
class A {};
void f(A* a) {
shared_ptr<A> c(a);
}
int main() {
auto a = make_shared<A>();
auto b = a.get();
f(b);
return 0;
}
在f
范圍的末尾,我的程序崩潰了。 是什么原因造成的? 是否有試圖刪除的東西不存在?
您有兩個不相關的共享指針,它們都試圖管理同一資源。 這導致不確定的行為。 特別是,它們都將在超出范圍時嘗試刪除資源。
一般來說,只是不要這樣做:)
class A {};
void f(A* a) {
shared_ptr<A> c(a);
}
int main() {
auto a = make_shared<A>();
auto b = a.get();
f(b);
return 0;
}
這里發生的是您最初的make_shared()
正在創建一個擁有A
的shared_ptr
。 調用f(b)
,您正在創建另一個不相關的共享指針,該指針也認為它擁有相同的數據。 當函數調用f()
結束時,本地共享的ptr變量將被銷毀。 這將檢查引用計數是否為零(將為零),然后刪除該對象。 然后,當主函數結束時,運行局部變量a
的析構函數,檢查引用計數是否為零(再次為零),因此嘗試再次刪除相同的數據。 兩次刪除是導致崩潰的原因。
有兩種解決方案:最簡單的就是不處理原始指針,而直接將shared_ptr
傳遞給f()
。 這樣,引用計數將正常工作,並且數據將僅被破壞一次。
另一種方法是讓您的類A
從std::enable_shared_from_this
公開繼承。 然后,您可以使用shared_from_this()
方法從原始指針“恢復”共享指針(具有正確的引用計數),即
class A : public std::enable_shared_from_this<A> {};
void f(A* a) {
shared_ptr<A> c = a->shared_from_this();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.