Std::string:: c_str() и временные
Является ли следующий код С++ корректным:
void consumer(char const* p)
{
std::printf("%s", p);
}
std::string random_string_generator()
{
// returns a random std::string object
}
consumer(random_string_generator().c_str());
Проблема с этим заключается в том, что после создания временного объекта std::string и принятия указателя c_str() ничто не мешает уничтожению объекта std::string (или, может быть, я ошибаюсь?). Не могли бы вы указать мне стандарт, если код в порядке, несмотря на все. Он работает, когда я тестирую g++.
Ответы
Ответ 1
Указатель, возвращаемый std::string::c_str()
, указывает на память
поддерживаемый строковым объектом. Он остается в силе до тех пор, пока не будет
функция вызывается для строкового объекта, или строковый объект
подорванный. Строковый объект, о котором вы беспокоитесь, является временным.
Он будет разрушен в конце полного выражения, а не раньше и
не после. В вашем случае конец полного выражения после
вызовите consumer
, чтобы ваш код был безопасным. Это было бы не так, если consumer
сохранил указатель где-нибудь, с идеей использовать его позже.
Время жизни временных рядов строго определено с С++ 98.
До этого он варьировался в зависимости от компилятора и кода, который вы
написанный не работал бы с g++ (pre 1995, грубо — g++
изменил это почти сразу, когда комитет по стандартам проголосовал за него).
(Тогда не было std::string
, но те же самые проблемы влияют
любой пользовательский строковый класс.)
Ответ 2
Временное время жизни std::string
распространяется только за пределы, где возвращается consumer
, поэтому можно безопасно использовать что-либо в этой строке непосредственно из consumer
. Что не в порядке - это сохранить значение, возвращаемое c_str
, и попытаться использовать его позже (временное будет уничтожено, и мы можем только догадываться, что вы найдете на другом конце указателя).
Ответ 3
Временное выражение, возвращаемое функцией random_string_generator(), можно безопасно использовать в функции consumer().