Дан фрагмент на C++: std::string& f(){ std::string s="tmp"; return s; } — найдите ошибку, объясните последствия и покажите корректные варианты реализации
Ошибка: функция возвращает ссылку на локальную переменную автоматической области видимости. Локальная переменная уничтожается при выходе из функции, поэтому возвращаемая ссылка становится висячей (dangling reference) — использование её приводит к неопределённому поведению (crash, мусор, кажущаяся «работа» в некоторых сборках). Примеры корректных вариантов: 1) Возврат по значению (простой и безопасный; NRVO/move оптимизации делают это эффективным): ``` std::string f() { std::string s = "tmp"; return s; } // или короче std::string f() { return "tmp"; } ``` 2) Возврат ссылки на объект с временем жизни, превышающим вызов (статический): ``` const std::string& f() { static const std::string s = "tmp"; return s; } ``` (статический объект живёт до завершения программы; const рекомендуется; изменяемые static — осторожно с потокобезопасностью) 3) Возврат умного указателя (явное владение): ``` std::unique_ptr f() { return std::make_unique("tmp"); } ``` 4) Использовать выходной параметр: ``` void f(std::string& out) { out = "tmp"; } ``` 5) Возврат std::string_view, если данные, на которые он ссылается, живут достаточно долго (например, строковый литерал): ``` std::string_view f() { return "tmp"; // безопасно: literal lives in static storage } ``` Коротко: не возвращайте ссылку на локальную переменную — используйте возврат по значению, static/динамическую память или другие подходящие механизмы владения/жизни объекта.
Примеры корректных вариантов:
1) Возврат по значению (простой и безопасный; NRVO/move оптимизации делают это эффективным):
```
std::string f() {
std::string s = "tmp";
return s;
}
// или короче
std::string f() { return "tmp"; }
```
2) Возврат ссылки на объект с временем жизни, превышающим вызов (статический):
```
const std::string& f() {
static const std::string s = "tmp";
return s;
}
```
(статический объект живёт до завершения программы; const рекомендуется; изменяемые static — осторожно с потокобезопасностью)
3) Возврат умного указателя (явное владение):
```
std::unique_ptr f() {
return std::make_unique("tmp");
}
```
4) Использовать выходной параметр:
```
void f(std::string& out) {
out = "tmp";
}
```
5) Возврат std::string_view, если данные, на которые он ссылается, живут достаточно долго (например, строковый литерал):
```
std::string_view f() {
return "tmp"; // безопасно: literal lives in static storage
}
```
Коротко: не возвращайте ссылку на локальную переменную — используйте возврат по значению, static/динамическую память или другие подходящие механизмы владения/жизни объекта.