Enr*_*lis 0 c++ std undefined-behavior language-lawyer indexoutofboundsexception
在cppreference上,我读到了以下内容std::vector<T,Allocator>::operator[]:
通过此运算符访问不存在的元素是未定义的行为。
标准草案中是否有类似的句子?或者说,我应该从标准的哪一部分推断出这个东西?
我想如果标准对此只字未提,那就会成为 UB。但我还没有找到任何相关信息std::vector<T,Allocator>::at,所以...
它是以一种非常迂回的方式指定的。
首先,成员不是vector直接指定的,而是通用的Sequence。您可以在此处找到规范:http://eel.is/c++draft/sequence.reqmts。
一、明显部分:at有子句
抛出:
out_of_range如果n >= a.size().
这就是at的行为的来源。
至于[],它说:
返回:
*(a.begin() + n)
所以效果与该表达式相同。我们需要遵循这个来找到未定义的行为。为此,我们需要查看迭代器要求。
现在 C++20 的要求几乎难以理解,但 C++17 的要求仍然存在并且确实适用。所以:
a + n(对于某些迭代器和a差异n)意味着tmp += n为tmp.ar += n意味着重复应用++r(或--r如果n是负数)。++r和都具有或分别是可解引用的*a先决条件。请注意,违反前提条件意味着 C++ 标准中未定义的行为。ra这就是事情变得非常复杂的地方。此时,我们需要将vector::begin和的规范拼凑在一起vector::end,以了解 的重复递增v.begin()最终将(如在v.size()应用程序之后)yield v.end(),它被指定为尾后迭代器。我找不到此类迭代器不可取消引用的明确声明,但http://eel.is/c++draft/iterator.requirements#general-7指定标准库假设它们不可取消引用,在向量的情况下这是真的。
因此,v[v.size()]相当于*(v.begin() + v.size()), 相当于*v.end(), 是未定义的行为。
Andv[v.size()+1]等价于*(v.begin() + v.size() + 1),它等价于*std::next(v.end()),它递增了尾后迭代器,从而导致未定义的行为。
| 归档时间: |
|
| 查看次数: |
138 次 |
| 最近记录: |