C++ C++;:向量<;Foo*>;使用reserve(),push_back()销毁值
标题有点让人困惑。以下是我当前困境的一个压缩版本: h类:C++ C++;:向量<;Foo*>;使用reserve(),push_back()销毁值,c++,vector,C++,Vector,标题有点让人困惑。以下是我当前困境的一个压缩版本: 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() { } }; class-Foo{ int x; Foo():x(0){} Foo(inty):x(
class Foo {
int x;
Foo(): x(0) { }
Foo(int y): x(y) { }
};
class B {
vector<Foo> list;
B() { }
};
class A {
vector<B> map;
A() { }
};
class-Foo{
int x;
Foo():x(0){}
Foo(inty):x(y){}
};
B类{
向量表;
B(){}
};
甲级{
矢量地图;
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;
void initialize(){
所有食品储备(…);
}
void generateMap(){
对于(…){
A A;
地图。推回(a);
对于(…){
B B;
map.back().map.push_back(b);
如果(…){
开关(…){
案例…:
富富(5),;
map.back().map.back().list.push_-back(foo);
allFoos.push_back(&map.back().map.back().list.back());
cout x;/#1
打破
}
cout x;/#2
}
cout x;/#3
}
cout x;/#4
}
cout x;/#5
}
int main(){
初始化();
生成映射();
}
当我运行代码时,我完全能够检索allFoos.back()
;我可以通过->
访问成员,使用MVC++Express 2013,我可以将鼠标悬停在allFoos
上,并获得其所有元素的列表……问题是,除了back()
元素之外的任何元素都是完全没有意义的
偶尔,成员值变得毫无意义;在#1、#2、#4和#5处,它将打印“5”。在#3,它将打印一个乱七八糟的数字+-几百万*
在多次中断、转储变量等之后,我确定问题在于push_back(…)
以某种方式改变了前面指针的位置,尽管reserve(…)
分配了远远超过足够的空间来容纳我需要的Foo*
s
我完全迷路了。我已经试了几个小时来理解为什么会发生这种情况,但没有结果。我已经仔细研究了数百个类似的问题,但没有一个能够帮助解决我的问题(除非我在将他们的解决方案应用于我自己的问题方面做得不够)
如果需要更多信息,可以提供
更新:
奇怪的是:如果我在Foo
类中创建一个printDetails()
成员函数,并将其用于allFoos.back()
at#5,所有Foo
的成员值都打印得非常精细,同样的悬停技术显示最后一个Foo*
是唯一一个细节完整的*
更新#2:
*我发现我说的每一句话都会随着跑步的不同而变化——每次,不同的位置都会打印不同的值,我无法确定一个位置可以提供一致的结果。似乎我在某个地方碰到了未定义的行为,但我似乎找不到…你的指针失效的地方,因为当你在向量中推送值时,一些最终会被扩展。因为向量连续存储数据,所以在重新分配时,现有值会移动到内存中的另一个位置。因此,原始指针指向以前的无效位置
如果您想继续像示例中那样填充向量,您应该事先为所有向量保留适当的大小。但是请记住,保留指向向量元素的原始指针最终会再次带来相同的问题。您确定示例和实际代码中的变量范围相同吗?你的描述听起来很像你的
map
变量在你迭代allFoos
之前被破坏了,这会使你所有的指针值指向无效数据在main.cpp
的开头定义了code>以及剩余的其他值。所有vector allfoo
的Foo都应该指向正确的位置…我不确定它们为什么停止随机操作,然后变得无用。这就是为什么我在开始时包括reserve(…)
,以防止重新分配。它大于放入其中的Foo*
s的数量。更新:等等……我想我现在明白了。让我看看是否可以事先为其他映射保留空间…@CarsonWilber您为包含原始指针的向量保留空间,而不是其他向量(在A
和B
中)啊!谢谢,我现在都明白了。我有办法解决这个问题吗?还是最好创建一个函数,在最后遍历映射并创建指针?@CarsonWilber这取决于allFoos
的用途;为什么要存储指向实例的指针?您已经可以在地图中访问它们。感谢您提供的所有帮助!我一直在胡思乱想,我想我已经找到了一个有效的系统:我将每个行星/恒星/飞船的位置存储为其对象中的整数,并将每个位置的行星/恒星/飞船的ID存储为位置对象中的整数/整数向量。基本上,一个没有指针的双向引用系统。比使用更流畅!