Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

accessing a variable from a shared pointer in c++ gives segmentation fault

I have a below snippet of c++ code which gives segfault. Could anyone explain why this gives segmentation fault?

#include <vector>
#include <memory>

class A {};

class B {
public:
    std::vector<std::shared_ptr<A>>& getListOfB();
    std::vector<std::shared_ptr<A>> m_ListOfB;
};

std::vector<std::shared_ptr<A>>& B::getListOfB()
{
    return m_ListOfB;
}

using BPtr = std::shared_ptr<B>;
using AVector = std::vector<std::shared_ptr<A>>;
using APtr = std::shared_ptr<A>;

int main() {
    std::shared_ptr<B> sharedPtrB = std::make_shared<B>();
    AVector &aVector = sharedPtrB->getListOfB();

    APtr report1 = std::make_shared<A>();
    aVector.push_back(report1);
    sharedPtrB = std::make_shared<B>();
    aVector = sharedPtrB->getListOfB(); // <-- fault happened

    return 0;
}

And running it gave me this stack trace.

0x00000000004013ea in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0xc50a25d35ec168ca) at /usr/include/c++/12/bits/shared_ptr_base.h:337
337           if (__atomic_load_n(__both_counts, __ATOMIC_ACQUIRE) == __unique_ref)
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.35-22.fc36.x86_64 libgcc-12.2.1-4.fc36.x86_64 libstdc++-12.2.1-4.fc36.x86_64
(gdb) bt
#0  0x00000000004013ea in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0xc50a25d35ec168ca) at /usr/include/c++/12/bits/shared_ptr_base.h:337
#1  0x00000000004015ef in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x41bf08, __in_chrg=<optimized out>) at /usr/include/c++/12/bits/shared_ptr_base.h:1071
#2  0x0000000000401536 in std::__shared_ptr<A, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x41bf00, __in_chrg=<optimized out>) at /usr/include/c++/12/bits/shared_ptr_base.h:1524
#3  0x0000000000401552 in std::shared_ptr<A>::~shared_ptr (this=0x41bf00, __in_chrg=<optimized out>) at /usr/include/c++/12/bits/shared_ptr.h:175
#4  0x000000000040315d in std::_Destroy<std::shared_ptr<A> > (__pointer=0x41bf00) at /usr/include/c++/12/bits/stl_construct.h:151
#5  0x0000000000402c15 in std::_Destroy_aux<false>::__destroy<__gnu_cxx::__normal_iterator<std::shared_ptr<A>*, std::vector<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > > > > (
    __first=<error reading variable: Cannot access memory at address 0xc50a25d35ec168d2>, __last=<error reading variable: Cannot access memory at address 0x39>) at /usr/include/c++/12/bits/stl_construct.h:163
#6  0x0000000000402659 in std::_Destroy<__gnu_cxx::__normal_iterator<std::shared_ptr<A>*, std::vector<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > > > > (
    __first=<error reading variable: Cannot access memory at address 0xc50a25d35ec168d2>, __last=<error reading variable: Cannot access memory at address 0x39>) at /usr/include/c++/12/bits/stl_construct.h:196   
#7  0x0000000000402069 in std::_Destroy<__gnu_cxx::__normal_iterator<std::shared_ptr<A>*, std::vector<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > > >, std::shared_ptr<A> > (
    __first=<error reading variable: Cannot access memory at address 0xc50a25d35ec168d2>, __last=<error reading variable: Cannot access memory at address 0x39>) at /usr/include/c++/12/bits/alloc_traits.h:850
#8  0x000000000040196e in std::vector<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > >::operator= (this=0x41bec0, __x=std::vector of length 0, capacity 0) at /usr/include/c++/12/bits/vector.tcc:244
#9  0x0000000000401281 in main () at snippet.cpp:29

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The stack trace indicates that an error occurred during the execution of the code. Specifically, it seems to be related to the assignment aVector = sharedPtrB->getListOfB(); in the main function.

The issue arises because aVector is a reference to sharedPtrB->getListOfB(), and when you reassign aVector to sharedPtrB->getListOfB(), the vector m_ListOfB inside B gets destroyed, causing the shared pointers to be released. Consequently, when the original vector is destroyed, it tries to release the shared pointers again, leading to a double deletion and resulting in undefined behavior.

To resolve this issue, you can either avoid reassigning aVector to a new vector or modify your code to handle the ownership of shared pointers properly.

Solution -1

std::shared_ptr<B> sharedPtrB = std::make_shared<B>();
AVector& aVector = sharedPtrB->getListOfB();

APtr report1 = std::make_shared<A>();
aVector.push_back(report1);
// Do not reassign aVector here

// Alternatively, if you need to assign a new vector,
// create a new shared pointer for B instead
sharedPtrB = std::make_shared<B>();
AVector& newVector = sharedPtrB->getListOfB();
// Use the newVector as needed

Solution -2

std::shared_ptr<B> sharedPtrB = std::make_shared<B>();
AVector& aVector = sharedPtrB->getListOfB();

APtr report1 = std::make_shared<A>();
aVector.push_back(report1);

sharedPtrB = std::make_shared<B>();
AVector newVector = sharedPtrB->getListOfB(); // Create a new vector, not a 
reference

// Use newVector as needed
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading