Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

smart_ptr to attribute of class segfault

I am wondering if this example would cause a segfault, because the dtor of the object is called an I am still holding a shared_ptr to an attribute of the object.

struct foo{
    std::shared_ptr<std::string> const bar = std::make_shared<std::string>("foo");

    foo() {std::cout << "CTOR!" << std::endl;} 

    ~foo(){std::cout << "DTOR!" << std::endl;}
};
int main() {
    std::shared_ptr<std::string> ptr;
    {
        std::shared_ptr<foo> foo_ptr = std::make_shared<foo>();
        ptr = foo_ptr->bar;
    }
    std::cout << *ptr << std::endl;


    return 0;
}
like image 562
Exagon Avatar asked Feb 07 '23 22:02

Exagon


1 Answers

No it it won't. By assigning a std::shared_ptr to another you are denying it from dying.

This operation ptr = foo_ptr->bar; will increase the counter of the shared pointer by one. This will guarantee that the dynamically allocated object on the free store will still alive.

is it true even for attributes of a destroyed object?!

Yes, This is true. In non-formal talk,one of the uses of dynamically allocated memory is when you want your object to live more than its owner (another object, pointer...). So , it is perfectly fine the that object will live after the container object died.


Try to execute this code. It will make it clear fro you:

std::shared_ptr<std::string> ptr;
{
    std::shared_ptr<foo> foo_ptr = std::make_shared<foo>();
    std::cout <<"References Count:" << foo_ptr->bar.use_count()<<"\n";
    ptr = foo_ptr->bar;
    std::cout <<"References Count:" << foo_ptr->bar.use_count()<<"\n";
}
std::cout <<"References Count:" << ptr.use_count()<<"\n";
std::cout << *ptr << std::endl;

It will output:

CTOR!
References Count:1
References Count:2
DTOR!
References Count:1
foo

Online Demo

like image 76
Humam Helfawi Avatar answered Feb 09 '23 12:02

Humam Helfawi