简体   繁体   中英

A bug in std::shared_ptr?

What should happen when the following program is executed?

#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.
}

I tested this on both GCC and Visual Studio 2015 and in both cases the program crashes. What happens is the shared pointer decrements the count in its destructor, then ~test() is executed, which copies the shared pointer incrementing and then decrementing the count, triggering an infinite recursion of calls to ~test(). Oddly enough calling reset() doesn't trigger the problem.

I ran into this today because some old code that used a pre-C++11 version of shared_ptr, which doesn't have this double deletion bug, was updated to use std::shared_ptr. To my surprise, std::shared_ptr made the program crash. Is this really the intended behavior of std::shared_ptr?

You have violated a basic rule of C++ object lifetime: you cannot access an object after its lifetime has ended. The deletion of test can only be achieved if all shared_ptr instances have ended their lifetimes. Therefore, its destructor, and all code it calls, cannot access any shared_ptr instances that refers to itself.

To do otherwise invokes undefined behavior. This is not a bug in shared_ptr ; it's a bug in your code. It's just as much UB if test were an object in a vector<test> and tried to access that vector<test> instance in your destructor.

It's irritating that things that could be made to work don't for pedantic reasons.

This is not a "pedantic reason". It is impossible . a_test_object doesn't exist anymore; it's not a valid object.

It doesn't work for the same reason that returning a reference to a stack variable doesn't work. The object is gone at this point; you can't access it anymore.

So you'll need to restructure your code to deal with that fact.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM