Returning stack variable?

I guess you didn't really want to write Object notpointer(); as this actually declares a function called notpointer returning an Object. If you meant Object notpointer; the entities in question are call values. Values are, indeed, allocated on the stack or, when the happen to be members of objects, embedded into the object.

When returning anything, the entity being returned is copied or moved into the location where the actual return value is expected. Once the return value is constructed, the local object, i.e., those on the stack, go out of scope and are destroyed. Given that the local objects are going away anyway, the compiler is allowed to elide the copy and construct the object immediately in the correct location, even if the copy constructor and/or the destructor have side effects.

The difference between your two return statements is

  1. When using new std::string("pointer") you get an object allocated on the heap and you return a pointer to the object. It is very easy to leak that pointer and you'd be better off to put it immediately into a suitable object, e.g., a std::unique_ptr<std::string>:

    return std::unique_ptr<std::string>(new std::string("pointer"));
    

    This way, the pointer won't be leaked. Of course, you'd also change the return type to be a std::unique_ptr<std::string> instead a std::string*. Note, that heap allocations are generally fairly expensive.

  2. When using std::string("value") you just return a local variable. There is a good chance that the copy will be elided and the return value is constructed immediately in the location where it should go. There is no need to look after any resources as all objects involved will be destroyed automatically. There is no explicit heap allocation and stack allocation are very fast.

Of course, in the given example the std::string actually needs to allocate its internal representation in both cases. If the pointer is returned, it is guaranteed that there is no additional internal allocation. On the other hand, when return a std::string value and it actually needs to be copied indeed, the internal memory may need to be allocated for the copy. That is, when returning large objects, possibly requiring lots of memory allocations, the approach returning a value runs the risk that it needs to be copied. With the current C++ the objects are, however, moved in the worst case, i.e., there isn't as much of a concern about copying the objects as there was in C++03.


When you return by pointer, you need to return a dynamically allocated object the way that you show (i.e. returning a pointer to a stack object results in undefined behavior if it is dereferenced later). This creates a potential for memory leaks, because, like you have noted, that object needs to be deleted explicitly.

Returning by value, on the other hand (i.e. the second snippet) results in copying the object that you return from the stack object into the object that receives the return value:

std::string res = get_home_folder(); // std::string gets copied into res

Compilers can optimize this to avoid copying through return value optimization.