C++ 如何在向量中存储指向静态分配对象的指针?

C++ 如何在向量中存储指向静态分配对象的指针?,c++,pointers,reference,C++,Pointers,Reference,假设我想创建一个对象向量和指向这些对象的指针向量(我不能使用动态内存)。我将在下面的示例中这样做 #include <iostream> #include <vector> using namespace std; class Foo { public: int bar; Foo(int x) : bar(x) { } }; int main () { vector<Foo> foos; vector<Foo*> pFoo

假设我想创建一个对象向量和指向这些对象的指针向量(我不能使用动态内存)。我将在下面的示例中这样做

#include <iostream>
#include <vector>

using namespace std;

class Foo {
public:
  int bar;
  Foo(int x) : bar(x) {
  }
};

int main () {
  vector<Foo> foos;
  vector<Foo*> pFoos;
  for (int i = 0; i < 10; i++) {
    Foo foo(i);
    foos.push_back(foo);
    pFoos.push_back(&foos.back());
  }

  for (int i = 0; i < 10; i++) {
    cout << foos[i].bar << endl;
    cout << pFoos[i]->bar << endl;
  }
}

来自
pFoos
的第一个数字是错误的。此外,每次都会有大量的变化。我没有看到任何会导致这种未定义行为的东西。有人能告诉我我做错了什么吗?

向向量添加项会使以前的所有迭代器失效。如果向量需要重新分配其内部存储,则在向量上调用push_可能会使您以前从该向量获得的指针无效

如果你知道你永远不会再增长向量,那么这就行了:

for (int i = 0; i < 10; i++) {
  foos.push_back(Foo(i));
}

for (int i = 0; i < 10; i++) {
  pFoos.push_back(&foos[i]);
}
for(int i=0;i<10;i++){
foos.push_back(Foo(i));
}
对于(int i=0;i<10;i++){
pFoos.推回(&foos[i]);
}
或者正如罗德里戈所评论的:

foos.reserve(10)

for (int i = 0; i < 10; i++) {
  Foo foo(i);
  foos.push_back(foo);
  pFoos.push_back(&foos.back());
}

for (int i = 0; i < 10; i++) {
  cout << foos[i].bar << endl;
  cout << pFoos[i]->bar << endl;
}
foos.reserve(10)
对于(int i=0;i<10;i++){
富富(i),;
向后推(foo);
pFoos.push_back(&foos.back());
}
对于(int i=0;i<10;i++){

cout我想这不是一个好的编程方法。向量负责存储对象,它可能会重新分配内存以获得更大的内存块…因此,您的指针不再有效…

vector::push_back
可以移动元素,这就是地址无效的原因。您可以将向量的内存预加载到它的位置在开始将内容推送到向量之前,通过调用
reserve
来确定最终大小,或者您可以等到推完内容后再获取它们的地址


但是你说你“不能使用动态内存”.
vector
使用动态内存。

但是
foo
不是静态的,而是本地存储…@rodrigo我以为vector会复制它?下面是我对该评论的参考:嗯,是的,你是对的,你正在保存指向
矢量化的
副本的指针,而不是原始的。问题是MyTagel答案的问题:指针无效。并非每个
push_back
都会导致重新分配。仅当分配的空间用完时。将“will make”替换为“may make”并解决。值得注意的是调用
foos.reserve(10)
将阻止UB。对不起,是的,我在简化。谢谢,这是有意义的,我不知道。我将试用你的代码,然后如果它有效,我将接受它。两种解决方案都有效!谢谢各位。我会在3分钟内接受,如果允许的话。我知道vector使用动态内存,但我的意思是我不能做类似
new Foo()的事情
。不过谢谢你,我会试着预订。
foos.reserve(10)

for (int i = 0; i < 10; i++) {
  Foo foo(i);
  foos.push_back(foo);
  pFoos.push_back(&foos.back());
}

for (int i = 0; i < 10; i++) {
  cout << foos[i].bar << endl;
  cout << pFoos[i]->bar << endl;
}