Время жизни временной строки C++

Извиняюсь, поскольку я знаю, что похожие вопросы существуют, но я все еще не совсем ясен. Безопасно ли следующее?

void copyStr(const char* s)
{
    strcpy(otherVar, s);
}

std::string getStr()
{
    return "foo";
}

main()
{
    copyStr(getStr().c_str());
}

Временный std::string будет хранить возврат от getStr(), но будет ли он жить достаточно долго, чтобы я мог скопировать его C-строку в другое место? Или я должен явно сохранить для него переменную, например

std::string temp = getStr();
copyStr(temp.c_str());

person gimmeamilk    schedule 30.06.2014    source источник


Ответы (3)


Да, это безопасно. Временное из getStr живет до конца полного выражения, в котором оно появляется. Это полное выражение является вызовом copyStr, поэтому оно должно вернуться до того, как временное из getStr будет уничтожено. Этого более чем достаточно для вас.

person MSalters    schedule 30.06.2014

Временная переменная существует до конца полного выражения. Итак, в вашем примере

copyStr(getStr().c_str());

Возвращаемое значение getStr() будет жить до конца copyStr. Поэтому безопасно обращаться к его значению внутри copyStr. Конечно, ваш код потенциально все еще небезопасен, потому что он не проверяет, достаточно ли велик буфер для хранения строки.

person Konrad Rudolph    schedule 30.06.2014

Вы должны объявить временную переменную и присвоить ей возвращаемый результат:

...
{
  std::string tmp = getStr();
  //tmp live
  ...
}
//tmp dead
...

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

Редактировать: это безопасно, вы передаете его по скопированному значению (ваше редактирование было тяжелым и аннулировало мой ответ выше. Ответ выше касается первой версии)

copyStr(getStr().c_str()); передаст rvalue в copyStr()

person Community    schedule 30.06.2014
comment
Да, я перепутал L и Rvalue, извините. Отредактировано - person ; 30.06.2014
comment
Я не это имел в виду, остальное тоже неверно: «у временного должно быть имя» — нет, наоборот: у временного не может быть имени. - person Konrad Rudolph; 30.06.2014
comment
@KonradRudolph Я сказал: «Редактировать: вопрос аннулировал мой ответ выше». Посмотрите на первую версию до того, как он отредактировал. Он написал std::string getStr(); - person ; 30.06.2014
comment
Ну, ответ уже начинается с того, что вам нужно объявить временную переменную - они тоже не объявлены. Но мы с Конрадом используем формальный термин temporary, как он определен в стандарте ISO, и, очевидно, этот ответ использует (сбивающее с толку) другое значение. - person MSalters; 30.06.2014
comment
Я понимаю это как тот же формальный термин, что и вы, но здесь, очевидно, ОП имел в виду переменную, которую он назвал temp. Для пояснения я просто использовал термин «временный» в том же запутанном значении, что и в вопросе. Проверьте редакцию 0 вопроса и перечитайте мой ответ и, возможно, пересмотрите свой отрицательный голос. - person ; 30.06.2014