Data from std :: vector link gets corrupted after returning from function call

I have std::vector< tr1::shared_ptr<mapObject> >one that I am trying to create from the data contained in a compressed file. Here is the function I'm trying to do with:

    using std::tr1::shared_ptr;

    template<typename T>
    void loadSharedPtrVector(std::vector< shared_ptr<T> >& vect, TCODZip& zip)
    // the TCODZip is the compression buffer I'm loading the data from.  It's
    // working correctly and isn't really part of this problem.
    {
        vect.clear();

        // load the size of the saved vector
        int numT = zip.getInt();

        // load the saved vector            
        for(int i=0; i<numT; ++i)
        {
            int type = zip.getInt();
            shared_ptr<T> Tptr(new T);
            T newT = T::loadType(type, zip);                
            Tptr.reset(&newT);
            std::cerr << "load: " << Tptr->getPosition() << std::endl; // outputs correct values
            vect.push_back(Tptr);
        }
        for(int i=0; i<numT; ++i)
        {
            // outputs the last value pushed onto vect
            std::cerr << "loadDone: " << vect[i]->getPosition() << std::endl;
        }
    }

The above function is called by this bit of code here:

        typedef std::tr1::shared_ptr<mapObject> featurePtr;

        // 'features' is a std::vector<featurePtr>, 'zip' is a TCODZip previously declared
        utility::loadSharedPtrVector<mapObject>(features, zip);

        vector<featurePtr>::const_iterator fit;
        for(fit=features.begin(); fit<features.end(); ++fit) 
        {
            // outputs mostly garbage
            cerr << "afterCall: " << (*fit)->getPosition() << endl;
        }

When this is done, the operators cerrgive this result (each set of output files has ~ 50 lines, so I cut most for short):

load: (5,40)
load: (5,45)
load: (5,58)
(etc.  all 'load' lines are correct output)
load: (87,68)
load: (11,5)
loadDone: (11,5)
loadDone: (11,5)
loadDone: (11,5)
loadDone: (11,5)
loadDone: (11,5)
loadDone: (11,5)
(etc. all 'loadDone' lines are the same)
afterCall: (11,5)
afterCall: (10,1)
afterCall: (10,1)
afterCall: (10,1)
afterCall: (10,1)
afterCall: (10,1)
afterCall: (10,1)
(etc. all 'afterCall' lines are the same except for the first)

I apparently have some misconceptions regarding how shared_ptrs work. I realized that I was pushing copies Tptrto vect, and therefore all of its indices are the same, although I thought that declaring a new shared_ptr in a loop would make a separate pointer from others already in vect, but I think not.

, "afterCall" "loadDone" ( ). (10,1) (2274756,134747232) (134747232, 16), (10,1) , .

, shared_ptr. - , ? , , .

+3
2

:

     T newT = T::loadType(type, zip);
     Tptr.reset(&newT);

shared_ptr , . :

shared_ptr<T> Tptr( new T( T::loadType( type, zip )));
+3

, , shared_ptr, :

template<typename T>
void loadSharedPtrVector(std::vector<T> & vect, TCODZip& zip)
// the TCODZip is the compression buffer I'm loading the data from.  It's
// working correctly and isn't really part of this problem.
{
    vect.clear();

    // load the size of the saved vector
    int numT = zip.getInt();

    // load the saved vector            
    for(int i=0; i<numT; ++i)
    {
        int type = zip.getInt();
        vect.push_back(T::loadType(type, zip));
    }
    for(int i=0; i<numT; ++i)
    {
        // outputs the last value pushed onto vect
        std::cerr << "loadDone: " << vect[i].getPosition() << std::endl;
    }
}
0

Source: https://habr.com/ru/post/1752010/


All Articles