在我的代码中,有一个Node对象的全局 vector 和一个Node指针的局部 vector :
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
class Node {
int n;
public:
Node(int i) : n(i);
int getN() { return n; }
};
vector<Node> v;
int main() {
vector<Node*> p;
v.push_back(Node(1));
p.push_back(&v[0]);
printf("first node id : %d\n", (*p[0]).getN());
return 0;
}
我在全局 vector 中插入了一个节点对象,并在局部 vector 中插入了该对象的指针。我上面的代码的输出是:
first node id : 1
但是,如果我将主要功能更改为此:
int main()
{
vector<Node*> p;
v.push_back(Node(1));
p.push_back(&v[0]);
v.push_back(Node(2));
p.push_back(&v[1]);
printf("first node id : %d\n", (*p[0]).getN());
return 0;
}
该代码显示一个垃圾值:
first node id : 32390176
我不知道问题所在。
插入后
vector
数据结构是否会更改每个对象的引用?我怎样才能解决这个问题 ?
最佳答案
“vector 在插入后是否会更改引用?”
可能是的。当您添加/std::vector
其他元素时, push_back()
可能会重新分配其(堆)存储,使所有指针无效:
“我怎样才能解决这个问题?”
如果 vector 的容量由于插入而没有改变,则上述无效规则将不适用-因为 vector 不会不必要地重新分配存储空间。因此,如果在示例中将 vector 的容量预先设置为2(例如v.reserve(2)
),则指针将保持有效。如果您事先不知道大小,但是可以延迟第二个 vector 的构建(使用指针),则不必保留,只需在插入最后一个元素后就拥有大小。
上面的方法是,强烈建议不要使用。如果要使 vector 恒定(至少在要构造和使用第二个 vector 的函数范围内),则将有很强的保证不会重新分配。另外,如果您可以预先确定大小,则可以使用 std::array
,并且将指针用于该容器的存储更合适:
您可能还考虑将索引存储到 vector 中(尽管在那里, vector 可能会缩小,使索引无效,或者可能在中间插入元素等)。
无论如何,我怀疑您实际上可能不想做任何事情,即,对于一个可以用另一种方法完全解决的问题来说,这似乎不是一个很好的解决方案。
PS-如果 vector 具有custom allocator,则我编写的所有内容都可能无关紧要。
关于C++:指针 vector 在push_back()之后丢失引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34708189/