Нет утечек памяти, но случай 3 даже неясен.
Функция get()
возвращает копию строки, возможно, оптимизированную, поскольку std::string
является классом, а не указателем или чем-то еще. Он работает, с точки зрения пользователя, примерно так же, как и возвращение int
из функции: копия создается и возвращается и остается действительной вне области действия функции, чтобы разрешить назначение или использование. Без этого поведения возвращаемые значения вообще были бы невозможны.
Это относится к POD и классам очень похоже (хотя классу нужен конструктор копирования и тому подобное). Вы должны быть в состоянии сделать это почти для любого класса std
, хотя стоимость создания копии будет разной (например, возвращать std::vector<BigClass>(1000)
плохая идея). В зависимости от настроек ваш компилятор может оптимизировать копирование с помощью RVO.
Случай 1 использует это: копия присваивается str
, нет утечки памяти, нет проблем. Довольно просто.
Дело 2 сбрасывает копию, но все же проблем нет.
Случай 3 попытается взять адрес временного возвращаемого значения, которое будет быстро уничтожено компилятором (из-за неиспользования), и сделать ptr
висячий указатель. Любое использование ptr
после того, как временное значение исчезнет, приведет к неопределенному поведению, возможно, к нарушению доступа. Где и когда временное хранилище будет уничтожено, зависит от вашего компилятора, настроек и других вещей, на которые вы не можете положиться.
Правильная форма: 1 (хотя 2 также действительна, но не очень полезна).