Вопрос по stdstring, c++, stl – std :: string :: c_str () и временные

52

Правильно ли сформирован следующий код C ++:

<code>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());
</code>

Проблема, с которой я столкнулся, заключается в том, что после создания временного объекта std :: string и взятия указателя c_str () ничто не мешает уничтожить объект std :: string (или, может быть, я ошибаюсь?). Можете ли вы указать мне стандарт, если код в порядке, несмотря на все. Это работает, когда я тестирую с g ++.

Ваш Ответ

3   ответа
66

std::string::c_str() указывает на память, поддерживаемую строковым объектом. Он остается действительным до тех пор, пока не будет вызвана неконстантная функция для строкового объекта или пока строковый объект не будет уничтожен. Строковый объект, который вас беспокоит, является временным. Он будет уничтожен в конце полного выражения, а не до и не после. В вашем случае конец полного выражения находится после вызоваconsumer, значит, твой код в безопасности. Не было бы, если быconsumer где-то сохранил указатель, с идеей использовать его позже.

Время жизни временных рядов строго определено с C ++ 98. До этого он варьировался в зависимости от компилятора, и написанный вами код не работал бы с g ++ (до 1995 года, примерно - g ++ изменил это почти сразу, когда комитет по стандартам проголосовал за него). (Там не былоstd::string тогда тоже, но те же проблемы влияют на любой написанный пользователем класс строки.)

что если бы кто-то использовалc_str() const char* в последующем утверждении (все еще внутри функции, но вне первого утверждения)? Принесет ли это нам свисающий указатель? Alex Gidan
Я отвечаю сам ... В этом случае это будет недействительно: § 12.2 ... Временные объекты уничтожаются как последний шаг в оценке полного выражения (1.9), которое (лексически) содержит точку, в которой они были созданы. Это верно, даже если эта оценка заканчивается выдачей исключения. Alex Gidan
18

std::stringремя жизни @ простирается чуть дальше точки, гдеconsumer возвращает, поэтому безопасно использовать что-либо в этой строке прямо изнутриconsumer. Чтон ОК - сохранить значение, котороеc_str возвращает и попытается использовать его позже (временное будет уничтожено, и мы можем только догадываться, что вы найдете на другом конце указателя).

Можете ли вы дать подсказку относительно стандарта C ++ 03 или C ++ 11, пожалуйста? user1095108
@ user1095108 и время жизни аргументов функций можно получить из §3.2.2 и §3.7.2 в стандарте c ++ 03. juanchopanza
Время жизни временного объекта определено в §12.2. (Раздел 12 озаглавлен «Специальные функции-члены», и это не совсем то место, где вы ожидаете найти время жизни временных пользователей, но именно там оно и есть.) James Kanze
5

возвращаемое функцией random_string_generator (), можно безопасно использовать в функции consumer ().

Похожие вопросы