结束迭代器和分割故障
end iterator and segmentation fault
如果以此示例为例:
std::map<int,foo*> intmap;
fillMap(intmap);
// I will force this to end(), in real life this could be a "find" output
std::map<int,foo*>::iterator iter = intmap.end();
if(iter->second != 0)
iter->second->whatever();
我有分割故障(可以预料,示例没有检查" iter!= intmap.end()" 是故意的)在" whywhing()"呼叫上,但在" -> second" null指针检查:这是预期的行为吗?此seg故障会系统地在" whywhing()"调用上,还是取决于特定的运行时间内存条件?
事先感谢您的评论。giacomo
删除end()
和STL容器的前端迭代器是未定义的行为。您没有什么可以称呼预期的。一切都会发生,甚至可以起作用。它可能取决于很多因素,例如编译器/libs/os版本,运行时环境状态,调试/发布构建等。因此,您永远不应该假设如果您做肮脏的事情会发生什么。
您不能取消"结束"迭代器。请记住,iter->
与(*iter).
大致相同;也就是说,有一个解雇。
删除end()
迭代器是一种未定义的行为。它可能崩溃也可能不会崩溃。
您必须检查find
的返回值:
if(iter != intmap.end())
iter->second->whatever();
删除过去迭代器的结果当然是不确定的,因此不能保证它会做什么。
但是,考虑可能发生的事情可能具有启发性(在调试场景中很有用)。关联容器的典型实现是作为节点的二进制树,每个节点在迭代顺序中包含指向next
和previous
节点的指示,而迭代器则是围绕节点指针的薄包装器。同样,list
被实现为双链接列表,每个节点都包含next
和previous
节点的指针。由于过去的末端迭代器需要减少,因此最简单的实现是指一个始终存在的节点,并且previous
指针指向容器中的最后一个节点。
因为这个过去的节点始终需要存在,即使对于一个空容器,最简单的实现就是将其放置在容器类中,大多数库实现都将执行此操作。结果,其存储是自动的(功能 - 本地)存储,并且将被默认构造,因此取消给过去的迭代器将提供堆栈垃圾。
我们可以通过比较指针来检查一下:
#include <map>
#include <iostream>
int main() {
std::map<int, int> m;
std::cout << &m << ' ' << &*m.end() << ' ' << &m + 1 << 'n';
}
0xbf990034 0xbf990048 0xbf99004c
您可以看到,过去的节点的存储存储在map
的堆栈足迹中。
- 分割故障C++矩阵
- C ,二进制树的高度,而不是检查我的子树是否为空,而是在检查我的子树是否是叶子节点.抛出分割故障
- 我正在为此代码分割故障
- 在执行strcpy时获取分割故障错误
- 空隙指针分割故障
- Xcode会产生分割故障,而不是例外
- OPENCV C 中的分割故障误差
- 分割故障:核心倾倒C 矢量对字符串:
- C 2D数组导致分割故障(核心倾倒)
- 分割故障/错误读数变量-C 列表
- DLSYM导致分割故障
- 使用C 中的操作员删除的分割故障
- 使用Linux X64下的Libmozjs-52(SpidermonKey)进行分割故障
- 使用长变量时分割故障(11)错误
- C - 返回字符串时的分割故障
- 创建VertexArray时的分割故障
- 向量分割故障的向量
- 从std :: fileSystem ::路径对象的类中退出时的分割故障
- C 矢量分割故障
- 基于向量的数据格式的分割故障误差