我有一个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
。任何人都可以告诉我我是如何滥用它的吗?我在网上找到的教程在这方面并不是很有帮助。
答案 0 :(得分:3)
问题在于:
T newT = T::loadType(type, zip);
Tptr.reset(&newT);
你给堆栈内存shared_ptr
指针,它在函数返回时回收并且不再有效。从堆中分配:
shared_ptr<T> Tptr( new T( T::loadType( type, zip )));
答案 1 :(得分:0)
我在代码中发现了与Nikolai相同的缺陷,并删除了无用的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;
}
}