简体   繁体   中英

Is decrementing std::vector::begin undefined, even if it is never used?

Note that, contrary to the many questions on the subject (and probably why I can not find a satisfactory answer to this question neither on google nor on stackoverflow), I never dereference *(begin() - 1)


My requirements are to:

  • iterate backwards
  • use functions that do not take reverse iterators, in this example vector::erase()
  • try to keep the code clean, so try to avoid the mental juggling of:

    vector.erase(rev_it.base() - 1)

    (What should the reverse iterator be now to get the the next element in the iteration ? The iterator returned by erase() ? + 1 , probably ? - 1 , unlikely ?)

What I've come up with is:

for (auto it = vector.end(); it-- != vector.begin(); ) {
    if (condition(*it)) {
        it = vector.erase(it);
    }
}

This seems to work, as it-- returns the iterator's value and then only decrements it, meaning the iterator is always decremented after the check but before entering the loop body .

In particular:

When entering the loop

  • if vector.end() == vector.begin() the vector is empty and we exit the loop immediately
  • if vector.end() != vector.begin() then we enter the loop, with the first loop body execution with it == vector.end() - 1

When erasing elements

vector.erase(it) returns the following element in the vector, so decrementing the iterator at every iteration gets us to consider exactly once every element in the vector.

When exiting the loop

At the last execution of the loop's body, it == vector.begin() , so the next time we try the loop condition:

  • the condition returns false
  • it is decremented one last time
  • we exit the loop

That is, my code does seem to compute the iterator position begin() - 1 but never accesses it , nor uses it for comparisons or anything like that.

Is this undefined behaviour?

Do I risk a segfault or something? Or just accessing uninitialized data maybe? Nothing at all because the iterator is discarded before being used in anyway? Is there no way of knowing?

How about

for (auto it = vector.end(); it != vector.begin(); ) {
    --it;
    ... rest of the loop body

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM