删除映射和分割错误中的一个过去结束元素
deletion of one past end element in map and segmentation fault
当我尝试使用erase
从map
中删除end()
元素时,我在编译中没有遇到任何问题,但是在后来打印map.begin()
键/mapped_value时,我遇到了分段错误:
//RELEVANT HEADERS
//main function starts
map<int, string> m;
m[0] = "hello";
m[1] = "Mello";
m.erase(m.end());
cout<<(m.begin())->second;
输出:Segmentation fault
我的问题是:在尝试删除end()
元素时,映射m
的结构不会发生任何事情,因为end
指的是一个经过真正的结束元素,所以真正触发该segmentation fault
的是什么,因为内存结构仍然与删除前相同。
正如你在cppreference关于std::map::erase
的文档中看到的那样,传递给它的迭代器必须是调用erase
的容器的有效迭代器,并且它必须是可取消引用的。
迭代器end()
不可取消引用。因此,将其传递给erase
违反了erase
的前提条件,这意味着您的程序具有未定义的行为。
未定义的行为意味着无法保证程序将做什么(或它是否会编译(,因此它完全有可能一直工作到程序的稍后某个地方和/或您遇到分段错误。这些是未定义行为的可能表现。
实际上,erase
调用可能会取消引用迭代器中包含的某个指针,该指针不指向任何元素并触发分段错误。但这是一个依赖于标准库实现的实现细节,无论如何都无关紧要,因为规则是由语言给出的,上面描述了。
std::map::erase()
可以采用以下三种类型的参数之一:
- 迭 代
- 迭代器范围
- 键值
您正在传递一个迭代器,但它是end()
,它比映射中的最后一个元素过去一个。根据 cpp 对std::map:erase()
的偏好:
迭代器 pos 必须有效且可取消引用。因此结束(( 不能使用迭代器(有效,但不可取消引用( 作为 POS 的值。
因此,要使std::map::erase()
使用迭代器,指向的元素必须是映射中的有效元素。否则,所有的赌注都会关闭,你可能会得到不确定的行为。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '