Unusual behavior with auto while traversing a dynamic vector

北城余情 提交于 2019-12-01 05:24:21

In addition to the problem pointed out by songyuanyao's answer, the code you present is undefined behavior. First, it is possible that the vector needs to reallocate because of a push_back, and then all iterator are invalidated and thus incrementing the loop variable is undefined behavior.

Looking at the documentation for push_back:

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

, I would say that appending to the vector in a range-based for statement is undefined behavior in any case, because the end iterator is always invalidated. The range-based for stores a copy of the initial end()-iterator, and this iterator is invalidated after the first push_back. This matches to your output, because it still points to the original end of the three-element vector. However, you should not rely on this behavior.

Unfortuantely, I could not find a rigid definition of "invalid iterator" semantics in the standard. §24.2.1.11 says that invalid iterators may be singular, but only states that dereferencing them may be undefined behavior. There is no semantics for comparing them, but given the fact that one implementation for vectors is to use the next memory address following the internal storage, and that address changes when the vector reallocates, I would say that the loop is undefined behavior.

This is called Range-based for loop.

6.5.4$1 The range-based for statement [stmt.ranged]:

In each case, a range-based for statement is equivalent to

{
  auto && __range = range-init;
  for ( auto __begin = begin-expr,
             __end = end-expr;
        __begin != __end;
        ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}

Note the equivalent pseudocode, __end (and __begin) will be set only once at the start of the loop. In your case, after the push_back at the last time of loop, the iterators might be invalid. If yes, the increment and comparsion on them will be implementation dependent. That means, as one of the possibilities, __end and __begin will remain the same, and loop count won't change.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!