 
                            ...
- As an argument to non-member functions swap(),operator>>(), andgetline().
- As an argument to basic_string::swap().
- Calling data()andc_str()member functions.
- Wiki Markup - Calling non-const member functions, except {{operator\[\]()}}, {{at()}}, {{begin()}}, {{rbegin()}}, {{end()}}, and {{rend()}}.
- Wiki Markup - Subsequent to any of the above uses except the forms of {{insert()}} and {{erase()}} which return iterators, the first call to non-const member functions {{operator\[\]()}}, {{at()}}, {{begin()}}, {{rbegin()}}, {{end()}}, or {{rend()}}.
Non-Compliant Example 1
The following non-compliant example copies the null-terminated byte string input into the string email, replacing ';' characters with spaces. This example is non-compliant because the iterator loc is invalidated after the first call to insert(). The behavior of subsequent calls to insert is undefined.
| Code Block | 
|---|
| 
char input[] = "bogus@addr.com; cat /etc/passwd";
string::iterator loc;
string email;
// copy into string converting ";" to " "
for (size_t i=0; i <= strlen(input); i++) {
  if (input[i] != ';') {
    email.insert(loc++, input[i]);
  }
  else {
    email.insert(loc++, ' ');
  }
} // end string for each element in NTBS
 | 
Compliant Solution 1
In the following compliant solution, the value of the iterator loc is updated as a result of each call to insert so that the insert() method is never called with an invalid iterator. The updated iterator is then incremented at the end of the loop.
| Code Block | 
|---|
| 
char input[] = "bogus@addr.com; cat /etc/passwd";
string::iterator loc;
string email;
// copy into string converting ";" to " "
for (size_t i=0; i <= strlen(input); i++) {
  if (input[i] != ';') {
    loc = email.insert(loc, input[i]);
  }
  else {
    loc = email.insert(loc, ' ');
  }
  ++loc;
} // end string for each element in NTBS
 | 
Non-Compliant Example 2
In this non-compliant example, the string s}  is initialized as "rcs" and the  {{string iterator si is initialized to the beginning of the string. The size of s is three, and we'll assume the capacity is fifteen. The for loop appends 20 characters to the end of the sting. As a result, the si iterator is invalided because the capacity of the string is exceeded requiring a reallocation. As a result, the call to insert() results in undefined behavior.
| Code Block | 
|---|
| 
string s("rcs");
string::iterator si = s.begin();
for (size_t i=0; i<20; ++i) {
  s.push_back('x');
}
s.insert(si, '*');
 | 
Compliant Solution 2
The relationship between size and capacity makes it possible to predict when a call to a non-const member function will cause a string to perform a reallocation. This in turn makes it possible to predice when an insertion will invalidate references, pointers, and iterators (to anything other than the end of the string).
...
The intent of these iterator invalidation rules is to give implementors greater freedom in implementation techniques. Some implementations implement method version versions that do not invalidate references, pointers, and iterators in all cases. Check with the documentation for your implementation before attempting to access a (potentially) invalid iterator. Document any violation of the semantics specified by the standard for portability.
...
- Meyers 01 Item 43: Prefer algorithm calls to hand-written loops.
- ISO/IEC 14882-2003 21.3 Class template basic_string.