Возврат объекта в стеке по значению - PullRequest
1 голос
/ 24 февраля 2012

Когда у меня есть не динамически выделенный объект, и я возвращаю его по значению:

string get()
{
    string str("hello");
    return str;
}

Есть шансы получить утечку памяти? Я делаю несколько примеров:

int main(int argc, char** argv)
{
    string str=get(); // case 1
    get();              // case 2
    string* ptr=&get();    // case 3
}

В каких случаях происходит утечка памяти?

Ответы [ 3 ]

7 голосов
/ 24 февраля 2012

Нет утечек памяти, но случай 3 даже неясен.

Функция get() возвращает копию строки, возможно, оптимизированную, поскольку std::string является классом, а не указателем или чем-то еще. Он работает, с точки зрения пользователя, примерно так же, как и возвращение int из функции: копия создается и возвращается и остается действительной вне области действия функции, чтобы разрешить назначение или использование. Без этого поведения возвращаемые значения вообще были бы невозможны.

Это относится к POD и классам очень похоже (хотя классу нужен конструктор копирования и тому подобное). Вы должны быть в состоянии сделать это почти для любого класса std, хотя стоимость создания копии будет разной (например, возвращать std::vector<BigClass>(1000) плохая идея). В зависимости от настроек ваш компилятор может оптимизировать копирование с помощью RVO.

Случай 1 использует это: копия присваивается str, нет утечки памяти, нет проблем. Довольно просто.

Дело 2 сбрасывает копию, но все же проблем нет.

Случай 3 попытается взять адрес временного возвращаемого значения, которое будет быстро уничтожено компилятором (из-за неиспользования), и сделать ptr висячий указатель. Любое использование ptr после того, как временное значение исчезнет, ​​приведет к неопределенному поведению, возможно, к нарушению доступа. Где и когда временное хранилище будет уничтожено, зависит от вашего компилятора, настроек и других вещей, на которые вы не можете положиться.

Правильная форма: 1 (хотя 2 также действительна, но не очень полезна).

2 голосов
/ 24 февраля 2012

Поскольку вы не выделяете динамически ни одной памяти в куче (используйте new или malloc и друзей), ни один из ваших примеров не будет пропущен.

1 голос
/ 24 февраля 2012

Для классов std и простого типа «никогда» не должно быть утечки. Для вас таможенные классы зависит от вас, чтобы создать класс, который правильно распределяет и освобождает свои внутренние ресурсы правильно.

...