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

206 views Asked by At

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.

3

There are 3 answers

0
David Schwartz On BEST ANSWER
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.

6
cehnehdeh On

New will dynamically allocate a new variable of that type. You can use it for any type. You will definitely need to call delete in order to free that memory.

You can't return new as a reference. You're trying to cast from a pointer to an class, and that doesn't work.

0
Andreas DM On

Could it cause memory leaks?

Yes. When you use pointers with new, you need to explicitly free that memory with delete.
If you're not very careful, chances are you will leak that memory.

The below code returns a pointer to the new allocated memory, i.e the beginning of that memory.

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

Smart pointers can make your life easier by managing their lifetime, and free the memory for you. Example:

shared_ptr<Object> var = make_shared<Object>();

(If you know the object won't be shared, you could use unique_ptr)

Or more relevant to you:

shared_ptr<Object> func()
{
    return make_shared<Object>();
}

int main()
{
    shared_ptr<Object> var = func();
}