Search code examples
c++vectorshared-ptrsmart-pointerspush-back

Read Access Violation using Smart Pointers


I am trying to use push_back as part of a member function in class StrBlobm to add elements to a vector in a shared pointer also contained in StrBlobm, but I keep getting this error:

Exception thrown: read access violation. std::_Vector_alloc,std::allocator >,std::allocator,std::allocator > > > >::_Myend(...) returned 0xC. occurred

I have similar trouble using iterators to print from the vector inside the shared pointer as well. What is causing this violation, and how do I fix it?

#include <memory>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <initializer_list>

class StrBlobm {
public:
    StrBlobm() = default;
    StrBlobm(std::initializer_list<std::string> il) :
        mydata(std::make_shared<std::vector<std::string>>(il)) {};

    void add(std::string& a)
    {
        mydata->push_back(a);
    }

private:
    std::shared_ptr<std::vector<std::string>> mydata;
};

int main()
{
    StrBlobm myblob;
    std::ifstream is;
    is.open("somefilepathtotxtdocument.txt");
    while(is)
    {
        std::string mystr;
        std::getline(is, mystr);
        myblob.add(mystr);
    }
    is.close();
    return 0;
}

Solution

  • Your constructor StrBlobm(std::initializer_list<std::string> il) is not called.

    But StrBlobm() is called, and there is no initialize code for mydata member variable. (It means, mydata is just pointing nullptr and you should not access with -> keyword)

    You should code like follows. (It's just one example.)

    #include <memory>
    #include <string>
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <initializer_list>
    
    class StrBlobm {
    public:
        StrBlobm() :
            mydata(std::make_shared<std::vector<std::string>>()) { // initialize mydata
        }
    
        StrBlobm(std::initializer_list<std::string> il) :
            mydata(std::make_shared<std::vector<std::string>>(il)) 
        {
        };
    
        void add(std::string& a)
        {
            mydata->push_back(a);
        }
    
    private:
        std::shared_ptr<std::vector<std::string>> mydata;
    };
    
    int main()
    {
        //call StrBlobm's default constructor (the constructor that takes no parameters.)
        StrBlobm myblob; 
    
        std::ifstream is;
        is.open("somefilepathtotxtdocument.txt");
        while (is)
        {
            std::string mystr;
            std::getline(is, mystr);
            myblob.add(mystr);
        }
        is.close();
        return 0;
    }