访问子范围外但父范围内的元素是否安全?涉及vector、span、list
问题解答
关于std::vector与std::span的场景
- 结论:从C++标准的严格定义来说,解引用
sub.begin()-1属于未定义行为,但实际运行中大概率能拿到元素2。 - 具体分析:
std::span的迭代器是随机访问迭代器,基于vector的span,其迭代器本质就是原生指针。sub.begin()对应原vector的arr.begin()+2(指向元素3),sub.begin()-1指向的元素2确实在原vector的有效内存范围内。但标准只保证span的迭代器可以安全访问span自身覆盖的范围(也就是元素3、4、5),跨出这个范围的操作不在标准保障范围内,属于依赖编译器实现的灰色地带。 - 额外提醒:你确实可以通过原生指针的方式访问到元素2,但用span的迭代器这么做,违背了span作为"子范围视图"的设计意图,也不符合迭代器的使用规范,不建议这么写。
关于std::list的场景
- 这情况完全不同:
std::list的迭代器是双向迭代器,根本不支持-1这种随机访问操作,直接写list_iterator -1编译器会直接报错。 - 就算忽略语法问题,list的元素是分散存储的,每个节点的内存地址不连续,迭代器偏移的行为完全不可预测,绝对是不安全的,属于明确的未定义行为。
内容的提问来源于stack exchange,提问作者hopeless-programmer
相关产品推荐
相关产品推荐

