为什么 std::vector::insert 使插入点之后的所有迭代器无效

2023-11-26

When insert-ing 成std::vectorC++ 标准确保插入点之前的所有迭代器都保持有效,只要capacity未耗尽(参见[23.2.4.3/1]或std::vector 迭代器失效).

不允许插入点之后的迭代器保持有效(如果容量未耗尽)的理由是什么?当然,他们会指向一个不同的元素,但是(从假定的实现来看)std::vector)仍然应该可以使用这样的迭代器(例如取消引用它或递增它)。


您似乎认为“无效”迭代器只是使用时会引发崩溃的迭代器,但标准的定义更广泛。它包括迭代器仍然可以安全地取消引用的可能性,但不再指向它期望指向的元素。 (这是“未定义行为”观察的一个特例does not意思是“你的程序将立即崩溃”;它也可能意味着“你的程序将默默地计算出错误的结果”,甚至“不会发生任何明显的错误”this执行。”)

更容易证明为什么这是一个问题erase:

#include <vector>
#include <iostream>
int main(void)
{
    std::vector<int> a { 0, 1, 2, 3, 4, 4, 6 };

    for (auto p = a.begin(); p != a.end(); p++) // THIS IS WRONG
        if (*p == 4)
            a.erase(p);

    for (auto p = a.begin(); p != a.end(); p++)
        std::cout << ' ' << *p;

    std::cout << '\n';
}

在 C++ 的典型实现中,该程序不会崩溃,但会打印0 1 2 3 4 6, 而不是0 1 2 3 6正如可能的预期,因为擦除第一个4 无效的 p——通过将其推进到第二个4.

您的 C++ 实现可能有一个特殊的“调试”模式,在该模式下该程序does运行时崩溃。例如,对于 GCC 4.8:

$ g++ -std=c++11 -W -Wall test.cc && ./a.out
 0 1 2 3 4 6

but

$ g++ -std=c++11 -W -Wall -D_GLIBCXX_DEBUG test.cc && ./a.out
/usr/include/c++/4.8/debug/safe_iterator.h:307:error: attempt to increment 
    a singular iterator.

Objects involved in the operation:
iterator "this" @ 0x0x7fff5d659470 {
type = N11__gnu_debug14_Safe_iteratorIN9__gnu_cxx17__normal_iteratorIPiNSt9__cxx19986vectorIiSaIiEEEEENSt7__debug6vectorIiS6_EEEE (mutable iterator);
  state = singular;
  references sequence with type `NSt7__debug6vectorIiSaIiEEE' @ 0x0x7fff5d659470
}
Aborted

请务必了解该程序会引发未定义的行为无论哪种方式。只是在调试模式下未定义行为的后果更为严重。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 std::vector::insert 使插入点之后的所有迭代器无效 的相关文章

  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐

  • Angular 2 Animate - 更改路线/组件时“* => void”过渡没有可见效果

    使用 Angular 2 Animate RC2 在官方文档的帮助下 以及 Matias 在 YT 频道上一个月前的 ng conf 动画视频中使用的代码 除了最关键的部分之外 我一切正常 更改路由器链接 组件时 我似乎无法让离开过渡 动画
  • tidyverse 未加载,它显示“命名空间‘vctrs’0.2.0 已加载,但需要 >= 0.2.1”

    强文本我在安装时不断遇到问题tidyverse包 这使我无法实现许多文本处理任务 这个问题与 2017 年以来许多以前的线程中提到的问题相同 因为当我输入library tidyverse 或者尝试打开其他相关包 他们总是说需要0 2 1版
  • 为什么二元 + 运算符不能与两个 &mut int 一起使用?

    fn increment number mut int this fails with binary operation cannot be applied to type mut int let foo number number let
  • Eclipse - java.lang.ClassNotFoundException

    当尝试从 Eclipse 中启动 JUnit Test 时 我收到 ClassNotFoundException 从控制台运行 mvn test 时 一切正常 另外 Eclipse 中也没有报告任何问题 我的项目结构如下 parent pr
  • 非静态回调如何在本机代码中工作?

    问这个问题有点奇怪 因为我的代码看起来不应该工作 但它确实工作 虽然我没有抱怨 但我想确认为什么 哈哈 简而言之 我有一个 C 本机 DLL 根本没有 CLR 托管支持 它接受来自 C 代码的回调 Native端存储了一个stdcall回调
  • 将 mySQL 查询作为 cron 作业运行?

    我想清除 SQL 数据库中超过 1 周的所有数据 并且我想每晚执行此操作 所以 我要设置一个 cron 作业 如何查询mySQL而无需每次都手动输入密码 PHP中的查询如下 mysql query DELETE FROM tbl messa
  • 将字符“00:00:00”转换为日期时间“00:00:00”

    我的问题来自这个问题 问题有以下字符串 x lt 2007 02 01 00 00 00 y lt 02 01 2007 00 06 10 如果您尝试将此字符串转换为日期类对象 则会发生一些有趣的事情 这是 nrusell 答案的示例 as
  • 如何将 na.rm 作为参数传递给 tapply?

    我想从数据框中计算平均值和标准差 其中一列用于参数 一列用于组标识符 使用时如何计算它们tapply 我可以用sd v1 group na rm TRUE 但无法适应na rm TRUE使用时进入语句tapply omit na是没有选择
  • Android 多重通知在点击时发送相同的数据

    Android 中的通知在点击时具有相同的意图 我在安装主题后发送通知 考虑我安装了 4 个主题 通知窗口中出现了 4 个通知 但是当我单击每个通知时 它将启动特定的活动 但意图是每个意图具有相同的数据 我的代码是这样的 SuppressW
  • 无法从“const wchar_t *”转换为“_TCHAR *”

    TCHAR strGroupName NULL const TCHAR strTempName NULL Assign some value to strTempName strGroupName tcschr strTempName 92
  • 管理 TPL 队列

    我有一项运行各种服务器扫描的服务 所涉及的网络可能非常庞大 数十万个网络节点 该软件的当前版本使用的是我们设计的队列 线程架构 该架构可以工作 但效率不高 尤其是因为作业可能会产生处理不好的子项 V2 即将推出 我正在考虑使用 TPL 看起
  • Java 标签不规则(可能是错误?)

    如果我们看一下Java标准 14 7 我们看到语句可能有标签前缀 例如 标签声明 标识符 声明 理论上 标签应该能够标记任何后续语句 因此 例如 以下内容将相应编译 public class Test public static void
  • OpenCV unproject 2D 指向具有已知深度“Z”的 3D

    问题陈述 我正在尝试将 2D 点重新投影到其原始 3D 坐标 假设我知道每个点的距离 继OpenCV 文档 我设法让它以零失真的方式工作 然而 当存在扭曲时 结果就不正确 目前的方法 因此 我们的想法是反转以下内容 分为以下内容 By 使用
  • 使用 jQuery 的“是”或“否”确认框

    我想要使 用 jQuery 发出 是 否 警报 而不是 确定 取消 按钮 jQuery alerts okButton Yes jQuery alerts cancelButton No jConfirm Are you sure func
  • Qt XML 中属性的顺序不正确

    我有以下代码 element clear element setTagName accountpoint element setAttribute code QString ID CONST serial element setAttrib
  • 自动构建 NuGet 包,包括引用的依赖项

    我想要运行本地 内部 NuGet 存储库 我想我已经弄清楚如何 重用 现有的 NuGet 包 方法是将它们包含在使用 NuGet 的虚拟项目中并扫描包文件以获取我的本地缓存 nupkg files but 如何创建 nuget 包 nupk
  • 将 2D 数组转换为 3D numpy 数组

    我创建了一个 numpy 数组 数组的每个元素都包含相同形状的数组 9 5 我想要的是一个 3D 数组 我尝试过使用 np stack data list map lambda x getKmers x 9 data getKmers cr
  • RabbitMQ / AMQP 中的消息组

    ActiveMQ JMS 有一个内置机制 可确保在使用竞争消费者模式时 共享公共标头 即 JMSXGroupID 标头 的消息始终由队列的同一使用者使用 队列的消费者完全不知道实际的标头值 因为具有公共标头的消息的保证是在服务器端而不是消费
  • 估计未定义表面的梯度

    我想估计一个梯度 斜率和坡向 不明确的表面 即函数未知 为了测试我的方法 这里是测试数据 require raster require rasterVis set seed 123 x lt runif 100 min 0 max 1 y
  • 为什么 std::vector::insert 使插入点之后的所有迭代器无效

    When insert ing 成std vectorC 标准确保插入点之前的所有迭代器都保持有效 只要capacity未耗尽 参见 23 2 4 3 1 或std vector 迭代器失效 不允许插入点之后的迭代器保持有效 如果容量未耗尽