Search code examples
c++dynamic-memory-allocation

Is the object being returned temporary or anonymous, and could it cause memory leaks?


First off, when returning an unnamed object such as:

Object* func() { return new Object(); }

is that an anonymous variable, temporary variable, neither, or both? Does having it unnamed cause it to be temporary- as in it goes out of scope once func returns? Could I extend its scope by assigning it to a pointer or reference in the calling code block or would that be illegal/dangerous?

My second worry is that since it is created with new if I were to:

Object *var = func()

somewhere else, would I need to delete it afterwards? If I did not delete it I'm assuming that would cause a memory leak.

If instead I returned a reference:

Object& func() { return new Object(); }

and I assigned the new object to a pointer or reference, would accessing the object be illegal/dangerous?

Also, if I am missing any other terminology here, please say something about it.


Solution

  • Object* func() { return new Object(); }
    

    This allocates an object with new (that must be freed with delete or there will be a leak) and returns a pointer to it by value.

    Object& func() { return new Object(); }
    

    This is illegal. It claims it returns a reference to an Object, but new Object returns a pointer to an object. If we fix that:

    Object* & func() { return new Object(); }
    

    We still have a problem -- this allocates an object with new and returns a reference to a temporary pointer to it. This is illegal -- you can't return a reference to a temporary. It's no different from:

    Object* & func() { Object* j = new Object(); return j; }
    

    It should be clear that this is invalid. You're returning a reference to j, but j no longer exists after you return.

    Though it's not idiomatic, you could do this:

    Object& func() { return *(new Object()); }
    

    This allocates a new Object, and returns a reference to it. The Object is not a temporary, so this is safe. The caller would still have to delete it to avoid leaks.

    The object you allocated and the pointer to it that's returned by new are two different (but related) things.

    The idiomatic way to do this is just to return the object by value. If you must dynamically allocate it, you should use some kind of smart pointer to avoid manually managing the lifetime.