В одной из моих программ мне приходится взаимодействовать с устаревшим кодом, который работает с const char*
.
Допустим, у меня есть структура, которая выглядит так:
struct Foo
{
const char* server;
const char* name;
};
Мое приложение более высокого уровня имеет дело только с ними std::string
, поэтому я подумал об использовании std::string::c_str()
для возврата const char*
указателей.
Но какова продолжительность жизни c_str()
?
Могу ли я сделать что-то подобное, не сталкиваясь с неопределенным поведением?
{
std::string server = "my_server";
std::string name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
// We use foo
use_foo(foo);
// Foo is about to be destroyed, before name and server
}
Или я должен сразу скопировать результат c_str()
в другое место?
Спасибо.
.c_str()
. Я не понимал, почему иногда получаю только части струны, пока не понял, чтоconst char*
не вечно живет, а пока струна не будет уничтоженаОтветы:
c_str()
Результат становится недействительным , еслиstd::string
разрушаются или если функция - члена Неконстантной строк называются. Итак, обычно вам нужно сделать копию, если вам нужно сохранить ее.В случае вашего примера кажется, что результаты
c_str()
используются безопасно, потому что строки не изменяются в этой области. (Однако мы не знаем, чтоuse_foo()
или~Foo()
могли бы делать с этими значениями; если они копируют строки в другом месте, тогда они должны делать настоящую копию , а не просто копироватьchar
указатели.)источник
non-const member function of the string is called.
?const
ключевым словом. Такая функция может изменить содержимое строки, и в этом случае строке может потребоваться перераспределить память для версии строки с завершающим нулем в конце, возвращаемой функциейc_str()
. Например,size()
иlength()
areconst
, поэтому вы можете вызывать их, не беспокоясь об изменении строки, ноclear()
это не такconst
.Технически ваш код в порядке.
НО вы написали таким образом, чтобы облегчить взлом для тех, кто не знает кода. Единственное безопасное использование c_str () - передача его в качестве параметра функции. В противном случае вы откроете для себя проблемы с обслуживанием.
Пример 1:
Итак, для обслуживания сделайте это очевидным:
Лучшее решение:
Но если у вас есть строки const, они вам действительно не нужны:
ХОРОШО. По какой-то причине вы хотите, чтобы они были строками:
почему бы не использовать их только в вызове:
источник
Он действителен до тех пор, пока с соответствующим
string
объектом не произойдет одно из следующих событий :Вы в порядке со своим кодом, если не измените эти
string
объекты после того, какc_str()
s скопированы,foo
но доuse_foo()
вызова.источник
Возвращаемое значение c_str () действительно только до следующего вызова непостоянной функции-члена для той же строки
источник
const char*
Вернулся изc_str()
действителен только до следующего неконстантного вызова кstd::string
объекту. В этом случае все в порядке, потому что выstd::string
все еще находитесь в области действия в течение всего времени существования,Foo
и вы не выполняете никаких других операций, которые могли бы изменить строку при использовании foo.источник
Пока строка не уничтожена и не изменена, можно использовать c_str (). Если строка изменена с использованием ранее возвращенного c_str (), определяется реализацией.
источник
Для полноты, вот ссылка и цитата с cppreference.com :
источник