An interesting note about smart pointers

In the past few days, I am more curious about whether the C++ smart pointer will be destroyed after leaving the scope. The doubt comes from a small code written by myself.

 

int count = 0;
vector<weak_ptr<Observer>> observers;
typedef std::vector<weak_ptr<Observer>>::iterator Iterator;
while (1) {
    shared_ptr<Foo> p(new Foo);
    weak_ptr<Foo> w(p);
    observers.push_back(w);
    Iterator it = observers.begin();

    while(it != observers.end())
    {
        cout<<w.lock()<<endl;
        it++;
    }
    if(count == sum)
    {
        break;
    }
}

In this piece of code, I will be very curious to find that the smart pointer p hangs after the first call, because the weak_ptr pointer can determine whether an object is alive. Of course, you should not think that I frequently make_shared on the stack. The pointer will change. If you apply on the stack, it will always be the memory address! Then I went to check the information and wrote the following code

int main()
{
//    pthread_t thread1;
//    pthread_t thread2;
//    pthread_t thread3;
//    pthread_create(&thread1, nullptr,threadOne,nullptr);
//    pthread_create(&thread2,nullptr,threadTwo,nullptr);
//    pthread_create(&thread3,nullptr,threadThree,nullptr);
//
//    pthread_join(thread1,nullptr);
//    pthread_join(thread2,nullptr);
//    pthread_join(thread3,nullptr);
    weak_ptr<Foo> globalPtr;
    {
        auto p = make_shared<Foo>();
        weak_ptr<Foo> p2(p);
        globalPtr = p2;
        cout<<globalPtr.lock()<<endl;
    }
    cout<<globalPtr.lock()<<endl;
}

This code is actually more interesting. After going out of scope, globalptr is destroyed, and the output is

0x5628df8eae80
0

In fact, after the smart pointer goes out of scope, it will trigger the destruction process and reduce the counter. If the counter is 0, the smart pointer will be destroyed naturally, because weak_ptr cannot increase the counter (weak reference) of shared_ptr. At this time, after going out of scope, The counter of p is 0, which is destroyed at this time, and the globalptr is naturally destroyed, so 0 will appear. Of course, if we replace globalptr with weakptr, there is no problem.

Guess you like

Origin blog.csdn.net/qq_32783703/article/details/105262274