2

So this is the situation:

vector <string>::iterator * it;
{
    vector <string> v{"asd", "asd"};
    auto iter = v.begin();
    it = new vector <string>::iterator(iter);
}
(**it) = string("asd");

Now, i can't find any resources on the web that tells me if this is UB or if it's valid code.

My question so is:
when i create a iterator, if that iterator has a lifetime longer than the container that refers to, is undefined behavior or is defined somewhere in the standard?

Berto99
  • 7,767
  • 2
  • 7
  • 22
  • 1
    why would you dynamically create an iterator? And why would you want to assign something to a vector element of a vector that is already gone? – 463035818_is_not_a_number Apr 13 '20 at 20:03
  • I couldn't back this up with reference to the standard, but it seems obvious to me that if you used the iterator it would be UB, but if it just exists you're fine. – john Apr 13 '20 at 20:04
  • i don't want to do that, but i'm building a container similar to vector, and i want to know if i have to manage this situation or if also in the STL is UB @idclev463035818 – Berto99 Apr 13 '20 at 20:04
  • ok, not saying that the question is non-sense, only the code ;). The interesting thing is that even this exhaustive answer seems not to mention that case: https://stackoverflow.com/questions/6438086/iterator-invalidation-rules – 463035818_is_not_a_number Apr 13 '20 at 20:05
  • @john thanks, but if i run this code there is no error during runtime, and clang doesn't generate any warning... – Berto99 Apr 13 '20 at 20:05
  • No error during runtime doesn't mean you don't have UB, as I'm sure you know. – john Apr 13 '20 at 20:06
  • I am pretty sure that it is UB, but not confident enough to write an answer. See here: https://en.cppreference.com/w/cpp/container I guess the vector going out of scope counts as "any method which removes one or more elements from the container." – 463035818_is_not_a_number Apr 13 '20 at 20:07
  • I found other SO answers which claim that using an invalidated iterator is UB. – Kenny Ostrom Apr 13 '20 at 20:08

1 Answers1

2

In your posted code,

(**it) = string("asd");

causes undefined behavior.

*iter is an iterator but the corresponding vector is not alive by the time you reach that line. Hence, **iter is analogous to dereferencing dangling pointer. BTW, that does not change if you use just an iterator instead of an iterator*.

The following code also causes undefined behavior.

vector <string>::iterator it;
{
    vector <string> v{"asd", "asd"};
    auto iter = v.begin();
    it = iter;
}
(*it) = string("asd");
R Sahu
  • 196,807
  • 13
  • 136
  • 247