Какое значение имеет строковый элемент данных? - PullRequest
1 голос
/ 11 сентября 2009

Строковые данные

Что меня особенно смущает, так это утверждение

"Его содержимое гарантированно останется неизменным только до следующего вызова неконстантной функции-члена строкового объекта."

Может кто-нибудь уточнить, что это значит? Когда использовать это и когда избегать этого?

Ответы [ 3 ]

5 голосов
/ 11 сентября 2009

Они означают, что вы можете сохранить указатель и использовать его позже. Если какой-то неконстантный метод вызывается между двумя доступами, содержимое буфера, на которое установлен сохраненный указатель, может измениться, и вы столкнетесь с неожиданным поведением.

4 голосов
/ 11 сентября 2009
const char* data() const;

Это говорит о том, что const char *, возвращаемый путем вызова str.data(), не изменится, если кто-то не изменит строку, из которой он получен. Когда кто-то вызывает непостоянную функцию-член, возвращаемый указатель может быть недействительным или может указывать на данные, отличные от тех, на которые он указывал сразу после возврата функции str.data().

Это означает, что вы можете передать возвращенные данные, например, в функции C. Это означает, что вы не должны делать что-то вроде:

const char *old = str.data();
size_t      len = str.length();
...call a function that modifies str...
// cout << old << endl;
// Since old is not guaranteed to be null terminated (thanks MSalter),
// do something else with the old data instead of writing to cout.
// Inventiveness not at a high this morning; this isn't a particularly
// good example of what to do - a sort of string copy.
char buffer[256];
memcpy(buffer, old, MIN(sizeof(buffer)-1, len));
buffer[len] = '\0'; 

К тому времени, когда будет выполнено копирование памяти I / O , old может быть недействительным, а len также может быть неправильным.

1 голос
/ 11 сентября 2009

Иногда вам нужно иметь доступ к строке, отформатированной в виде массива символов - обычно потому, что вам нужно передать строку какой-то функции, которая ожидает такую ​​строку (например, strcmp). Вы можете сделать это, используя элементы data или c_str, но вы должны соблюдать правила вызова функции, которые четко изложены в указанной вами ссылке:

Возвращенный массив указывает на внутреннее местоположение, которое не должно быть изменено прямо в программе. это содержимое гарантированно останется без изменений только до следующего звонка непостоянная функция-член строковый объект.

Вы не можете изменять массив символов - строковый объект предполагает, что вы этого не делаете, и если вы это сделаете, это приведет к неопределенному поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...