开发者

data from a std::vector reference becomes corrupt after return from function call

I have a std::vector< tr1::shared_ptr<mapObject> > that I'm trying build from data contained in a compressed file. Here's the function I'm attempting to do that 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
            s开发者_如何学运维td::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 run, the cerr statements give this output (each set of output has ~50 lines, so I cut out most for brevity):

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 about how shared_ptrs work. I realized that I'm pushing copies of Tptr into vect, and that's why all of its indices are the same, although I thought that declaring a new shared_ptr in the loop would make a separate pointer from the other ones already in vect, but I guess not.

I have no idea why the 'afterCall' set of output is different from the 'loadDone' set (except for that first value). In addition to (10,1) it has also output (2274756,134747232) and (134747232, 16), although it outputs (10,1) more than any other.

I suspect that my problem boils down to my misuse of shared_ptr. Can anyone tell me exactly how I'm misusing it? The tutorials I find online haven't been very helpful in this regard.


The problem is here:

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

You give shared_ptr pointer to stack memory, which is reclaimed at function return and is no longer valid. Allocate that from the heap:

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


I have spotted the same defect in your code as Nikolai did, and erased the shared_ptr which is useless:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜