Подтвердить что ты не робот

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++.

4b9b3361

Ответ 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().