在向vector添加更多元素之前引用vector元素

Taking reference to vector element before adding more element to vector

本文关键字:元素 vector 引用 添加 在向      更新时间:2023-10-16

考虑以下代码:

int main()
{
    std::vector<std::string> v;
    v.push_back("hello");
    v.push_back("stack");
    std::string &s = v[0];
    v.push_back("overflow");
    std::cout << s << std::endl;
    return 0;
}

运行(使用g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4)后,只打印空行,不打印hello。如果我注释掉v.push_back("stack");,则出现分段错误。

现在我明白为什么会这样了。向vector添加更多元素会触发引擎盖下的增长操作,并且我的旧引用在此之后变得无效。这不是我的问题。

我的问题是这种行为-修改引用/指针后的向量或其他STL容器-被定义为c++标准中的未定义行为?如果有,在哪里?如果没有,那么标准对这种情况是怎么说的?

c++ 14 [vector.capacity]/6:

重新分配使指向序列中元素的所有引用、指针和迭代器失效。

[向量。

我实际上找不到任何定义引用无效意味着什么的文本,但它显然暗示在无效后使用引用的值将是未定义的行为。

修改容器的行为并不仅仅因为您通过某种方式获得了迭代器、引用或指针而被禁止。可能无效的是迭代器、引用或指针本身。

§23.3.6.6[向量。(包括push_back成员族)

  1. 备注:如果新容量大于旧容量,将导致重新分配。如果没有重新分配,则之前的所有迭代器和引用插入点仍然有效。如果抛出的异常不是通过复制构造函数、移动构造函数、赋值操作符或将T的赋值操作符移到CC_6,或将其移到InputIterator操作中没有效果。插入单个元素时抛出异常元素的末尾,并且T是CopyInsertable或is_nothrow_move_constructible<T>::value为真,没有效果。类的move构造函数抛出异常非copyinsertable T,效果未指定。

如果没有调整大小,则只有插入点之后的引用、指针和迭代器(包括结束迭代器)无效。很好,但是如果重新分配会发生什么呢?有趣的是,我们发现:

§23.3.6.3[向量。能力)

  • 备注:重新分配使所有的引用、指针和引用序列中元素的迭代器。不重新分配将在调用后发生的插入期间发生的大小之前保留()向量大于capacity()的值。
  • 然而,我不完全相信这完全回答了你的问题。如果您想知道先前占用向量的内存发生了什么,这取决于标准库,但它不再包含可行的内容。容器不再拥有内存(据您所知),您也不拥有。
    相关文章: