C++ 这个std::cout最终会打印垃圾或其他意想不到的东西吗?
看看这段代码C++ 这个std::cout最终会打印垃圾或其他意想不到的东西吗?,c++,pointers,C++,Pointers,看看这段代码 class Obj{ public: int id; Obj(int id) : id(id){} }; int main() { std::vector<Obj> v; for(int i=0; i<3; i++) // add some elements v.push_back(Obj(i)); Obj& ref = v[2]; // grab references (two ways)
class Obj{
public:
int id;
Obj(int id) : id(id){}
};
int main()
{
std::vector<Obj> v;
for(int i=0; i<3; i++) // add some elements
v.push_back(Obj(i));
Obj& ref = v[2]; // grab references (two ways)
Obj* ref_bad = &v[2];
for(int i=3; i<100000; i++) // make the vector re-allocate
v.push_back(Obj(i));
std::cout << ref.id << std::endl; // prints 2
std::cout << (*ref_bad).id << std::endl; // prints 2, but always?
return 0;
}
类Obj{
公众:
int-id;
Obj(int-id):id(id){}
};
int main()
{
std::向量v;
对于(int i=0;i,您的程序具有未定义的行为
在v
上调用push\u back()
时,ref
和ref\u bad
无效
发件人:
如果新的size()
大于capacity()
,则所有迭代器和引用(包括结束迭代器的过去)都将无效。否则,只有结束迭代器的过去将无效
尽管有人可能会说,引用实际上是隐藏在伪装中的指针的语法糖,但它们却毫无魔力1
知道了这一点,很明显,如果您保留一个指向重新分配的内存的指针(=引用),这样的指针(=引用)将变得无效,因为它指向您不再拥有的内存,因此访问它是未定义的行为
请注意,对于STL容器,这都是有文档记录的-如果您查找std::vector::push_back
,您会发现,如果新大小大于当前容量,则可能会使所有迭代器和引用无效
这就是为什么在处理向量时,通常会保留索引,而不是迭代器或指针
我所能想到的引用的唯一魔力是,const
引用可以绑定到十个临时变量,并使它们在原始表达式的末尾保持活动状态(受一些规则的约束)
引用和指针处于悬空状态,因此行为未定义。因此,在这种情况下,保留所需项目的索引是最好的选择,而不是引用/指针?@FeloVilches,是的。当然。