簡體   English   中英

std :: shared_ptr中的錯誤?

[英]A bug in std::shared_ptr?

執行以下程序應該怎么辦?

#include <iostream>
#include <memory>

class test;
std::shared_ptr<test> a_test_object;
struct test
{
    ~test()
    {
        std::cout << "destroy test" << std::endl;
        auto ptr = a_test_object;
    }
};

int main()
{
    a_test_object = std::make_shared<test>();
    //a_test_object.reset();  // Uncomment this and it works fine.
}

我在GCC和Visual Studio 2015上都對此進行了測試,在兩種情況下程序均崩潰。 發生的事情是共享指針遞減其析構函數中的計數,然后執行〜test(),該操作復制共享指針遞增,然后遞減計數,從而觸發對〜test()的調用的無限遞歸。 奇怪的是,調用reset()不會觸發問題。

我今天遇到了這個問題,因為一些使用C_11之前版本的shared_ptr的舊代碼(沒有此雙重刪除錯誤)已更新為使用std :: shared_ptr。 令我驚訝的是,std :: shared_ptr使程序崩潰了。 這真的是std :: shared_ptr的預期行為嗎?

您違反了C ++對象生存期的基本規則:對象的生存期結束后,您將無法訪問該對象。 僅當所有shared_ptr實例的生命周期都已結束時,才能刪除test 因此,其析構函數及其調用的所有代碼都無法訪問引用其自身的任何shared_ptr實例。

否則會調用未定義的行為。 這不是shared_ptr的錯誤; 這是您代碼中的錯誤。 如果testvector<test>中的一個對象並嘗試訪問析構函數中的vector<test>實例,則這與UB一樣多。

令人討厭的是,本來可以工作的東西並不是出於腐的原因。

這不是“學究的原因”。 這是不可能的 a_test_object不再存在; 這不是有效的對象。

由於與返回對堆棧變量的引用不起作用相同的原因,它不起作用。 此時對象已消失。 您無法再訪問它。

因此,您需要重組代碼以應對這一事實。

暫無
暫無

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

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