修改了vector之后对vector.back()的引用的奇怪行为

时间:2013-11-20 14:23:04

标签: c++ c++11 vector reference

让我们从C ++中的示例代码开始:

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> vec;
    vec.push_back(0);
    for (int i = 1; i < 5; i++)
    {
        const auto &x = vec.back();
        std::cout << "Before: " << x << ", ";
        vec.push_back(i);
        std::cout << "After: " << x << std::endl;
    }
    return 0;
}

代码使用g++ test.cc -std=c++11 -O0进行编译,结果如下:

Before: 0, After: 0
Before: 1, After: 0  
Before: 2, After: 2
Before: 3, After: 3

我期待第二行输出

Before: 1, After: 1

因为x是对向量中项目的引用,不应通过将项目附加到向量来修改该项目。

但是我现在还没有阅读反汇编代码或进行任何其他调查。此外,我不知道这是否是语言标准中的未定义行为。

我希望对此进行解释。感谢。

2 个答案:

答案 0 :(得分:8)

如果我们查看push_back部分23.3.6.5 向量修饰符

draft C++ standard可能会导致重新分配:

  

void push_back(const T&amp; x);

     

void push_back(T&amp;&amp; x);

     
    
      

备注:如果新大小大于旧容量,则会导致重新分配。 如果没有重新分配,插入点之前的所有迭代器和引用仍然有效

    
  

我们可以看到back为我们提供了引用,因此如果有重新分配,它将不再是有效

答案 1 :(得分:4)

修改向量后,

vector迭代器(以及对元素的先前引用)可能会失效。使用它们是不安全的。