在我的代码中,有一个 Node 对象的全局向量和一个 Node 指针的本地向量:
#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;
}
我将一个节点对象插入到全局向量中,并将该对象的指针插入到本地向量中。我上面的代码的输出是:
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
数据结构在插入后更改每个对象的引用?
我怎样才能解决这个问题 ?
“向量在插入后会改变引用吗?”
可能是的。一个std::vector当您添加/时可能会重新分配其(堆)存储push_back()
附加元素,使所有指针无效:
迭代器[读:指针]失效
(用于操作)push_back
, emplace_back
...如果向量改变了容量,所有这些[即。所有迭代器都无效]。如果没有的话,只有end()
.
“我怎样才能解决这个问题?”
如果向量的容量不会因插入而改变,则上述失效规则不适用 - 因为向量不会不必要地重新分配存储空间。因此,如果您在示例中将向量的容量预设为 2(例如,v.reserve(2)
),指针将保持有效。如果您事先不知道大小,但可以延迟第二个向量(使用指针)的构造,则不必保留,只需在插入最后一个元素后即可获得大小。
上面的方法是非常不推荐, 然而。如果你要制作你的向量constant- 至少在您将构造和使用第二个向量的函数范围内 - 您将得到不重新分配的强有力保证。或者,如果您可以提前确定尺寸,则可以使用std::array,使用指向该容器存储的指针会更合适:
迭代器失效
通常,数组的迭代器在数组的整个生命周期中永远不会失效。
您也可以考虑存储indices到你的向量中(尽管向量也可能会缩小,使索引无效,或者你可能会在中间插入元素等)。
不管怎样,我怀疑你实际上可能不想做任何事情,也就是说,这似乎是一个不太好的解决方案,可以完全用不同的方法来处理。
PS - If the vector has a custom allocator then everything I've written might be irrelevant.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)