C++ 向量在将其元素的引用推回到自身时是如何工作的?

C++ 向量在将其元素的引用推回到自身时是如何工作的?,c++,C++,我首先声明一个名为test的string的vector。然后我把stringHello和World推回,让a成为test[0]的参考。然后我把a推回test中。然而,我在推回之前和之后分别打印了a,并观察到a在推回test之后变成了零。为什么a一文不值?当将其元素的引用(a)推回到自身时,向量是如何工作的?这是否意味着a不再是测试[0]的参考 谢谢 备注:如果我向后推测试[0],a也将变为空。但是test[0]仍然是“Hello” 更新: 我明白了,多亏了下面的答案和评论。我打印了test的si

我首先声明一个名为
test
string
vector
。然后我把
string
Hello
World
推回,让
a
成为
test[0]
参考。然后我把
a
推回
test
中。然而,我在推回之前和之后分别打印了
a
,并观察到
a
在推回
test
之后变成了零。为什么
a
一文不值?当将其元素的
引用
(a)
推回到自身时,向量是如何工作的?这是否意味着
a
不再是
测试[0]
参考
谢谢

备注:如果我向后推测试[0]
a
也将变为空。但是
test[0]
仍然是“Hello”

更新:

我明白了,多亏了下面的答案和评论。我打印了
test
size
capacity
,并观察到它们都是
2
。当执行
test.push_back(a)
时,向量
test
分配新内存并将其旧元素复制到新内存中。因此,
a
,它对旧元素的引用,变得未定义

下面是使用
reserve
的类似代码。我认为
a
未定义的原因与我原来的问题相同。(如果我错了,请告诉我。)

添加
a
的副本作为
test
的最后一个元素。
a
是对
test
中某个元素的引用这一事实根本不相关

在该调用之后,
a
可能是悬空引用。就像你在队伍中一样使用它

 cout << "2"<< a << "\n"; 

cout根据
std::vector
定义,由于
vector::push_back
使容器的现有引用无效,
string&a
变得未定义。看

如果新的size()大于capacity(),则所有迭代器和引用(包括结束迭代器的过去部分)都将无效。否则,只有结束迭代器的过去部分无效


因为你不知道在按下
a
之前向量的容量是多少,你不能确定你的引用没有失效;这是一种未定义的行为,在某些情况下可能“起作用”,但在其他情况下可以做任何事情。

push_back
上,所有迭代器、指针和对向量元素的引用都将无效(除了一些未测试的情况),谢谢。但是为什么
a
的副本会使
a
成为悬挂的参考?这不就是“抄袭”吗?为什么引用
a
变得未定义?现在我将
test替换为
string b=a
。把
a
复制到
b
和我原来的问题不一样吗?但是在将
a
复制到
b
之后,
a
不是未定义的,而是“Hello”(
test[0]
)。
std::vector::push_back
如果其当前容量不足以容纳新元素,则可能需要分配内存。当它这样做时,它会在将旧对象复制/移动到新内存后删除旧内存。因此,对旧对象的引用可能会变成悬空引用。
1Hello
2
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
     vector<string> test;
     test.push_back("Hello");
     test.push_back("World");
     string& a = test[0];
     cout << "1"<< a << "\n";
     cout << "size:" << test.size() << " capacity:" <<test.capacity() <<"\n";  
     test.reserve(3);       
     cout << "2"<< a << "\n"; 
} 
1Hello
size:2 capacity:2
2
test.push_back(a);          //or : test.push_back(test[0]);
 cout << "2"<< a << "\n";