...
- 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 Code Example
...
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 email;
string::iterator loc = email.begin();
// 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
...
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 email;
string::iterator loc = email.begin();
// 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 Code Example
...
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
...
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).
...