标题有点让人困惑。这是我当前困境的一个大大压缩的版本:
Classes.h:
class Foo {
int x;
Foo(): x(0) { }
Foo(int y): x(y) { }
};
class B {
vector<Foo> list;
B() { }
};
class A {
vector<B> map;
A() { }
};
main.cpp中:
vector<A> map;
vector<Foo*> allFoos;
void initialize() {
allFoos.reserve(...);
}
void generateMap() {
for (...) {
A a;
map.push_back(a);
for (...) {
B b;
map.back().map.push_back(b);
if (...) {
switch (...) {
case ...:
Foo foo(5);
map.back().map.back().list.push_back(foo);
allFoos.push_back(&map.back().map.back().list.back());
cout << allFoos.back()->x; // #1
break;
}
cout << allFoos.back()->x; // #2
}
cout << allFoos.back()->x; // #3
}
cout << allFoos.back()->x; // #4
}
cout << allFoos.back()->x; // #5
}
int main() {
initialize();
generateMap();
}
当我运行我的代码时,我完全能够检索allFoos.back()
;我可以通过->
访问成员,使用Break,使用MVC ++ Express 2013,我可以将鼠标悬停在allFoos
上并获得所有元素的列表...问题是,任何元素但back()
元素完全无意义。
偶尔,会员价值变得毫无意义; 在#1,#2,#4和#5,它将打印&#39; 5&#39;。在#3,它会打印一个乱码数字+ - 几百万。 *
在多次中断,转储变量等之后,我已经确定问题是push_back(...)
以某种方式改变了前面指针的位置,尽管reserve(...)
分配的远远不够空间可以容纳尽可能多的Foo*
。
我绝对迷路了。我已经尝试了几个小时才能理解为什么会这样,但无济于事。我已经看了几百个类似的问题,但没有一个足够接近我的问题(除非我不足以将他们的解决方案应用于我自己的问题。)
如果需要更多信息,可以提供。
更新
这里有什么陌生人:如果我在printDetails()
类中创建了一个Foo
成员函数,并将其用于#{1}}#5相反,所有allFoos.back()
的成员值都打印完全正常 - 并且相同的悬停技术显示最后Foo
是唯一具有详细信息的人完好。击> *
更新#2:
*我发现我说的所有内容都会根据运行情况而变化 - 每次,不同的位置会打印不同的值,而且我无法确定提供一致结果的位置。好像我在某个地方遇到了未定义的行为,但我似乎无法找到......
答案 0 :(得分:2)
您的指针无效,因为当您在向量中推送值时,某些指针最终会被扩展。由于向量连续存储数据,因此在重新分配时,现有值将移动到内存中的另一个位置。因此,您的原始指针指向先前的无效位置。
如果你想继续填充你的矢量,你应该预先为所有矢量保留适当的大小。但请记住,保持向量元素的原始指针最终会再次引发相同的问题。