Search code examples
c++c++17shared-ptrsmart-pointers

Modifying value of object pointed by a shared pointer


I have recently started working with shared pointers and need some help. I have a vector 1 of shared pointers to some objects. I need to construct another vector 2 of shared pointers to the same objects, so that modifying vector 2 would result in modification of vector 2. This is how my code looks like: This works fine

class A
{
    public:
    int a;
    A (int x) {
      a = x;
    }
    int print() {
        return a;
    }
};

int main()
{
    shared_ptr<A> ab = make_shared<A>(100);
    cout<< ab->print();
    
    shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
    shared_ptr<vector<shared_ptr<A>*>> vec2 = make_shared<vector<shared_ptr<A>*>>();
    vec2->push_back(&(*vec1)[0]);
    for (shared_ptr<A>* obj : *vec2) {
        *obj = make_shared<A>(100);
    }
    cout << (*((*vec1)[0])).a;   // Prints 100
    return 0;
}

But this gives a SEGV at the last line since vec1 is not populated:

class A
{
    public:
    int a;
    A (int x) {
      a = x;
    }
    int print() {
        return a;
    }
};

int main()
{   
    shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
    shared_ptr<vector<shared_ptr<A>>> vec2 = make_shared<vector<shared_ptr<A>>>();
    vec2->push_back((*vec1)[0]);
    for (shared_ptr<A> obj : *vec2) {
        obj = make_shared<A>(100);
    }
    cout << (*((*vec1)[0])).a;   // SIGSEGV
    return 0;
}

I want to understand why vec1 was not populated in the 2nd one and also would like to know if there is any other way of doing this. Thanks!


Solution

  • The code for the setup described in the comments could be:

    #include <vector>
    #include <memory>
    #include <iostream>
    using namespace std;
    
    struct A
    {
        int a;
        A(int a): a(a) {}
    };
    
    int main()
    {   
        auto p_vec1 = make_shared<vector<shared_ptr<A>>>();
        auto p_vec2 = make_shared<vector<shared_ptr<A>>>();
    
        for (int i = 0; i < 100; ++i)
            p_vec1->push_back( make_shared<A>(i) );
    
        for (int i = 0; i < 50; ++i)
            p_vec2->push_back( (*p_vec1)[i * 2] ); 
        
        (*p_vec1)[2]->a = 213;
        std::cout << (*p_vec2)[1]->a << '\n';    // print 213
    
        return 0;
    }
    

    In case you are unaware, the "outer" shared_ptr is unnecessary, you could just use two vectors .