簡體   English   中英

從shared_ptr獲取原始ptr,並使其再次共享

[英]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()正在創建一個擁有Ashared_ptr 調用f(b) ,您正在創建另一個不相關的共享指針,該指針認為它擁有相同的數據。 當函數調用f()結束時,本地共享的ptr變量將被銷毀。 這將檢查引用計數是否為零(將為零),然后刪除該對象。 然后,當主函數結束時,運行局部變量a的析構函數,檢查引用計數是否為零(再次為零),因此嘗試再次刪除相同的數據。 兩次刪除是導致崩潰的原因。

有兩種解決方案:最簡單的就是不處理原始指針,而直接將shared_ptr傳遞給f() 這樣,引用計數將正常工作,並且數據將僅被破壞一次。

另一種方法是讓您的類Astd::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();
}

您可以在此處閱讀有關enable_shared_from_this 信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM