在向vector添加更多元素之前引用vector元素
Taking reference to vector element before adding more element to vector
考虑以下代码:
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
成员族)
- 备注:如果新容量大于旧容量,将导致重新分配。如果没有重新分配,则之前的所有迭代器和引用插入点仍然有效。如果抛出的异常不是通过复制构造函数、移动构造函数、赋值操作符或将
T
的赋值操作符移到CC_6,或将其移到InputIterator操作中没有效果。插入单个元素时抛出异常元素的末尾,并且T
是CopyInsertable或is_nothrow_move_constructible<T>::value
为真,没有效果。类的move构造函数抛出异常非copyinsertableT
,效果未指定。
如果没有调整大小,则只有插入点之后的引用、指针和迭代器(包括结束迭代器)无效。很好,但是如果重新分配会发生什么呢?有趣的是,我们发现:
§23.3.6.3[向量。能力)
然而,我不完全相信这完全回答了你的问题。如果您想知道先前占用向量的内存发生了什么,这取决于标准库,但它不再包含可行的内容。容器不再拥有内存(据您所知),您也不拥有。
- 备注:重新分配使所有的引用、指针和引用序列中元素的迭代器。不重新分配将在调用后发生的插入期间发生的大小之前保留()向量大于capacity()的值。
相关文章:
- 使用运算符 [] 引用 std::vector 上最后一个元素时出现问题<>
- 对的排序向量 (std::vector<pair<int, int>>) 按对的第一个元素搜索并更新第二个元素值
- 为什么通过 vector<reference_wrapper> 的元素删除引用的值<T>不会使向量无效?
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- 如果变量数据包含大于 vector 所有元素的整数,则仅在视觉工作室上接收"矢量下标超出范围"?
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 除了 std::vector 之外,是否有一个 std 容器不会复制和销毁作为类的元素?
- 对 Vector 元素 (C++) 的push_back操作
- 从 std::vector 中选择一个元素,而不是给定元素
- 将 Vector<String > 元素复制到其他 Vector<String>* (1 作为
- 有没有更快的方法可以在 std::vector 中插入元素
- 如何在构造函数初始值设定项列表中使用 n 个元素初始化 std::vector<std::time_t>
- clang C++17 std::vector over align type 使用 -mavx 编译时元素 SIGSE
- 如何将 n 个连续元素插入到元素类型不可复制的 std::vector 中?
- 通过引用传递时访问std::vector的元素
- 有没有函数可以直接获取 std::vector 元素的大小?
- 如何非常快速地将数字添加到 Vector 中的一系列元素中
- 如何安全地擦除 std::vector 中的元素
- 如何在不使用 vector::erase() 的情况下编写自定义 Vector 方法来删除元素?
- 如何在一对集合的向量中插入元素?vector<pair<int,set<string>>>