c++ - Is it safe to access elements outside subrange but inside parent range? - Stack Overflow

Let's say I have an std::vector<int> arr of 5 elements { 1, 2, 3, 4, 5 }.Is it safe to get

Let's say I have an std::vector<int> arr of 5 elements { 1, 2, 3, 4, 5 }.

Is it safe to get a subrange from it like sub = std::span{ arr.begin() + 2, arr.end() } and dereference element at -1 like *(sub.begin() - 1)?

In terms of pointers this looks safe, but what about iterators? If this is safe for vector and span, what about list?

Let's say I have an std::vector<int> arr of 5 elements { 1, 2, 3, 4, 5 }.

Is it safe to get a subrange from it like sub = std::span{ arr.begin() + 2, arr.end() } and dereference element at -1 like *(sub.begin() - 1)?

In terms of pointers this looks safe, but what about iterators? If this is safe for vector and span, what about list?

Share Improve this question edited 10 hours ago Botje 31.3k4 gold badges34 silver badges47 bronze badges asked 10 hours ago hopeless-programmerhopeless-programmer 1,0007 silver badges21 bronze badges 2
  • 1 gsl::span asserts on out of bounds access, but the standard libraries don't do that. – Ahmed AEK Commented 10 hours ago
  • auto& two = *std::prev(std::addressof(*sub.begin())); would be safe though – Ted Lyngmo Commented 9 hours ago
Add a comment  | 

2 Answers 2

Reset to default 1

From the definition of LegacyBidirectionalIterator:

The begin iterator is not decrementable and the behavior is undefined if --container.begin() is evaluated.

And it - n is defined in terms of --, so no, this is not safe.

In terms of pointers this looks safe, but what about iterators?

This is unsafe, and it is reasonable to assume that library implementations will verify offsets to avoid them, e.g. MSV-STL when _ITERATOR_DEBUG_LEVEL is enabled.

In this case, ranges::subrange may meet your needs as long as the operation on the original iterator is safe, since it returns the original iterator-pair.

However, subscripting on a ranges::subrange may still be unsafe because its operator[] may still be aware of out-of-bounds:

auto sub = std::ranges::subrange{ v.begin() + 2, v.end() };
auto x = sub.begin()[-1]; // safe
auto y = sub[-1];         // unsafe, UB

So, in any case, even if you think it is safe, it is better not to try to access out-of-bounds elements to avoid potential undefined behavior.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743747764a4500326.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信