Время жизни возвращенных строк и их .c_str ()

Я встречал несколько экземпляров этого шаблона (с boost :: filesystem используется только в качестве примера):

boost::filesystem::path path = ...;
someFunctionTakingCStrings(path.string().c_str());

где

const std::string path::string() const
{
  std::string tmp = ...
  return tmp;
}

Хотя у меня никогда не возникало проблем с этим шаблоном, мне было интересно, когда строка, возвращаемая sting(), уничтожается и безопасен ли код, обращающийся к c_str(), как Время жизни c_str () привязано к времени жизни std :: string.


person PhilLab    schedule 20.12.2016    source источник
comment
Почему он помечен как вопрос C?   -  person rgmt    schedule 20.12.2016
comment
Потому что в нем есть c_str ()   -  person PhilLab    schedule 20.12.2016
comment
@PhilLab: но это не значит, что он компилируется на C ;-)   -  person Bathsheba    schedule 20.12.2016


Ответы (1)


someFunctionTakingCStrings(path.string().c_str()); безопасен, поскольку стандарт гарантирует, что время жизни анонимного временного path.string() сохраняется после вызова функции. Таким образом, указатель, возвращаемый c_str(), является допустимым параметром для someFunctionTakingCStrings.

const std::string path::string() const является безопасным, поскольку концептуально вы возвращаете копию значения tmp, хотя на практике компилятор оптимизирует копию значения (процесс, называемый оптимизацией именованного возвращаемого значения).

Что-то вроде const std::string& path::string() const с тем же телом функции, что и у вас, не будет определено (поскольку ссылка будет болтаться), и

const char* ub_server()
{
    std::string s = "Hello";
    return s.c_str();
}

также не определено, так как s находится вне области видимости к моменту возврата из функции.

Наконец, обратите внимание, что использование указателя на анонимный временный объект в качестве параметра при вызове функции не разрешено в стандартном C ++, хотя, к сожалению, Visual C ++ допускает это как расширение.

person Bathsheba    schedule 20.12.2016
comment
благодаря. Быстрое продолжение: Итак, functionTakingPointer(&path.string()) тоже будет в безопасности? - person PhilLab; 20.12.2016
comment
@PhilLab: Нет, это небезопасно в стандартном C ++. Я поставил это в конце ответа. - person Bathsheba; 20.12.2016
comment
хм, тогда я не совсем понял время жизни path.string (). Или анонимные временники - это отдельная глава, посвященная управлению памятью? - person PhilLab; 20.12.2016
comment
@PhilLab: Да, в основном это так. Приятного чтения на Рождество. - person Bathsheba; 20.12.2016