简体   繁体   中英

C++ Object is stored in stack or heap

I know this question has been asked a lot in SO as in Object creation on the stack/heap? To my understanding if an object is stored in Stack it will get popped if the variable gets out of scope. But when it come to automatic storage it confuses me how is it not in heap. I've read that using new and delete in C++ is not recommended (or even evil is the choice of word), because it will introduce memory leak. So I device a test code like these

#include <iostream>
#include <string>

class Cat
{
public:
    Cat(const std::string& name)
    {
        this->name = name;
        std::cout << "construct Cat " << this->name << std::endl;
    }
    ~Cat()
    {
        std::cout << "destruct Cat " << this->name << std::endl;
    }
    void feed()
    {
        std::cout << "feed Cat " << this->name << std::endl;
    }
private:
    std::string name;
};

Cat createFelix()
{
    Cat garfield("Garfield");
    Cat felix("Felix");
    garfield.feed();
    felix.feed();
    return felix;
}

void getAndFeedFelix()
{
    Cat justFelix = createFelix();
    justFelix.feed();
}

int main()
{
    getAndFeedFelix();
    std::cout << "bla bla blah" << std::endl;
}

and it resulted like these

construct Cat Garfield
construct Cat Felix
feed Cat Garfield
feed Cat Felix
destruct Cat Garfield
feed Cat Felix
destruct Cat Felix
bla bla blah

so in my conclusion, the function createFelix() is called from getAndFeedFelix() which returned a Cat (which stored in stack), that supposed to be popped from the stack after the function return, but the object is destructed after getAndFeedFelix() is out of scope, because of the automatic storage mecanism. How can this happen? If automatic storage is using heap and reference counting then it might be possible. Is my logic wrong?

You have discovered Return Value Optimization (specifically named return value optimization).

This function:

Cat createFelix()
{
    Cat felix("Felix");
    return felix;
}

Cat justFelix = createFelix();

looks like it should create a Cat , copy it, and destroy it. But as an optimization, createFelix() actually creates felix in the memory owned by justFelix . So we just create one Cat , with zero copies. Everything here is on the stack.

So then:

void getAndFeedFelix()
{
    Cat justFelix = createFelix(); // creates a cat
    justFelix.feed();              // feeds a cat
}                                  // destroys a cat

Which is the output you see.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM