c++ - 从函数调用返回后,来自 std::vector 引用的数据损坏

标签 c++ shared-ptr

我有一个 std::vector< tr1::shared_ptr<mapObject> >我正在尝试从压缩文件中包含的数据构建。这是我尝试使用的函数:

    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;
        }
    }

上面的函数被这段代码调用:

        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;
        }

运行时,cerr语句给出了这个输出(每组输出有 ~50 行,所以为了简洁我删掉了大部分):

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)

我显然对 shared_ptrs 的工作原理有一些误解。我意识到我正在推送 Tptr 的拷贝进入vect ,这就是为什么它的所有索引都相同的原因,尽管我认为在循环中声明一个新的 shared_ptr 会使一个单独的指针与 vect 中已有的其他指针分开。 ,但我想不是。

我不知道为什么“afterCall”输出集与“loadDone”输出集不同(第一个值除外)。除了(10,1)它还输出(2274756,134747232)(134747232, 16) , 虽然它输出 (10,1)比任何其他的都多。

我怀疑我的问题归结为我对 shared_ptr 的误用.谁能确切地告诉我我是如何滥用它的?我在网上找到的教程在这方面并不是很有帮助。

最佳答案

问题出在这里:

     T newT = T::loadType(type, zip);
     Tptr.reset(<b>&newT</b>);

您将 shared_ptr 指针指向堆栈内存,该内存在函数返回时被回收并且不再有效。从堆中分配:

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

关于c++ - 从函数调用返回后,来自 std::vector 引用的数据损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3129196/

相关文章:

c++ - 尝试访问 json 数据时获取 nullC++

c++ - BlackBerry 10 Cascades - 如何导航到另一个 CPP 类

C++11 多线程问题

c++ - 如何取得 std::unique_ptr 和 std::shared_ptr 的所有权

c++ - shared_ptr C++ 双重删除错误

c++ - std::shared_ptr<type>(new DerivedType(...)) != std::make_shared<type>(DerivedType(...))?

c++ - shared_ptr 尚未拥有的实例的 shared_from_this() 总是返回 null?

C++11:如果对象是使用 make_shared 构造的,如何删除它

c++ - 链接器输出文件属性文件与目标路径不匹配?

c++11 - 比较 shared_ptr 实例的有效情况