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.