Что возвращает метод c_str() из строкового класса?

Я хочу получить начальный адрес массива, который поддерживается классом строк.

string str="hey";
char* pointer=(char*)str.c_str();
  • Указывает ли указатель на адрес массива (поддерживается строковым классом)? или класс string создаст новый массив из динамической памяти и скопирует в него существующую строку и вернет ее адрес?

  • Если это не так, то как получить доступ к начальному адресу массива, который поддерживается классом строк?

Ответ 1

В стандарте С++ 11 явно указано, что .c_str() (а также новый .data()) должен возвращать указатель на внутренний буфер, который используется std::string.

Любая модификация std::string после получения указателя через .c_str() может привести к тому, что упомянутый char * возвращенный стал недействительным (то есть, если std::string внутренне пришлось перераспределять пробел).

В предыдущих версиях С++ реализация может вернуть что-либо. Но как стандарт не требует от пользователя освобождения от результата, я никогда не видел, чтобы какая-либо реализация возвращала что-то новое. По меньшей мере GNU gcc и MSVС++ STL-строка являются внутренними нулевыми массивами char, которые возвращаются c_str().

Так что безопасно предполагать (с нормальным для С++ предостережения), что в любой версии С++ в любой его реализации .c_str() будет возвращен внутренний буфер.

Другими словами, вы никогда не должны сохранять значение .c_str(), если не будете на 100% уверены, что он не изменит его размер в любое время в будущем (если это не const, то есть).

P.S. BTW, вы никогда не должны делать char* pointer=(char*)str.c_str();. Это const char *, и вы не должны изменять содержимое, отчасти потому, что выше - вы можете завершить переписывание памяти какого-либо другого объекта или развратить внутреннее состояние std::string, если реализация делает что-то фантастическое, например индексирование символов для более быстрого .find() (новее видели это, но эй - это инкапсуляция!)

Ответ 2

ПРИМЕЧАНИЕ. Мой ответ верен только для pre-С++ 11. Для С++ 11, это является правильным ответом.


  • Он возвращает C-строку с нулевым завершением. std::string сам по себе не заканчивается на нуль, поэтому реализация разрешена (и, вероятно, будет) возвращать вновь выделенный массив const char. Если создание std::string выходит за пределы области видимости или, если оно мутировано, строка c_str() -вернутая строка недействительна.

  • data() возвращает данные, но будьте осторожны, это не строка с нулевым завершением.

В любом случае вы должны настроить эти данные, как data(), так и c_str() указатели возврата на const char, и вы действительно не должны этого делать.

Например, std::string разрешены ссылки на подсчитанные строки (хотя это уже не является обычным явлением) или даже могут использовать фанковые схемы индексирования по их данным (но никогда не видели этого).

Ответ 3

Вы можете получить адрес начала строки char *address = &str[0];. Нет необходимости преобразовывать строку в представление c-строки.

Ответ 4

Если вы действительно хотите "данные" внутри строки, то string::data() - это функция, которую вы ищете.

Обратите внимание, что, подобно c_str(), это указатель const для данных - вы не должны изменять эти данные.

Ответ 5

В С++ 11 возвращаемый указатель указывает на внутренний массив, используемый в настоящее время строковым объектом для хранения символов, соответствующих его значению.

Подробнее см. http://www.cplusplus.com/reference/string/string/c_str/.