Переменная C ++ в стеке не освобождается в конце области действия функции - PullRequest
0 голосов
/ 10 июня 2018

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

class Foo
{
public:
    Foo(int bar)
    {
        this->bar = bar;
        std::cout << "Standard constructor called" << std::endl;
    }
    ~Foo()
    {
        std::cout << "Standard destructor called" << std::endl;
    }
    Foo(const Foo &foo)
    {
        std::cout << "Copy constructor called" << std::endl;
        this->bar = foo.bar;
    }
    inline int get_bar() { return bar; }
private:
    int bar;
};

Foo make_foo(int bar)
{
    Foo f1(bar);
    std::cout << "About to return foo with address of: " << &f1 << std::endl;
    return f1;
}

int main()
{
    Foo f2 = make_foo(3);
    std::cout << "New variable has address of: " << &f2 << std::endl;
    std::cout << "And a value of " << f2.get_bar() << std::endl;
}

Но кое-что, что я нахожу странным, происходит, когда язапустите этот код.Как и ожидалось, «стандартный конструктор называется» печатается и адрес foo в этой функции печатается.Но когда функция заканчивается, деструктор не вызывается, и f2 фактически имеет тот же адрес памяти, что и f1, хотя, насколько я понимаю, f1 должен был выйти из области видимости и освободить память, потому что он был в стеке, верно?Или это не ожидаемый результат в этой ситуации?

Я ожидаю, что конструктор копирования будет вызван для копирования f1 в f2, а затем для f1 будет вызван деструктор, а f2 займет другую памятьадрес.

Если кому-то интересно, это фактический вывод:

Standard constructor called                                                                          
About to return new foo with address of: 0x7fff518e5a88                                              
New variable has address of: 0x7fff518e5a88                                                          
And a value of 3                                                                                     
Standard destructor called     

Интересно, что когда я меняю тип возврата make_foo на ссылочный тип, функция выполняется почтикак я и ожидал, с f1 уничтожается и f2 копирует ненужные данные.

Это какой-то особый случай, когда переменная в стеке не освобождает свою память, когда ее возвращают для присвоения другой переменной, котораяЯ должен быть в курсе?

1 Ответ

0 голосов
/ 10 июня 2018

Компилятор выполняет оптимизацию возвращаемого значения (RVO).Вы можете прочитать об этом здесь: https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...