1

So I was writing a piece of code where I used new operator to create an object inside a local scope function and returned the reference as a pointer.

A* operator+(A that){
    int sumA = a + that.getA();
    int sumB = b + that.getB();
    return new A(sumA, sumB);
}

In my thought It would not work because the object was created inside the local scope and should be temporary, but it compiled and ran. Can anyone explain to me about this? I am sure there are other things that kinda have the ability of breaking the scope and stuff.. If possible, could you give me some examples? Appreciated!

user3513507
  • 87
  • 1
  • 7
  • possible duplicate of [When should I use the new keyword in C++?](http://stackoverflow.com/questions/655065/when-should-i-use-the-new-keyword-in-c) – aruisdante May 07 '14 at 03:26
  • 1
    @aruisdante How is this question a duplicate of the one you linked to? The OP is asking about why pointers can be returned without the object being pointed to "going out of scope". – Yong Jie Wong May 07 '14 at 03:31
  • @yjwong Because it demonstrates a clear misunderstanding of what ``new`` does. The linked duplicate explains. The question wouldn't be asked (or rather, a very different question would have been asked) if the OP understood what ``new`` did. – aruisdante May 07 '14 at 03:32
  • 2
    This is a bad idea because expressions like `a + b + c` won't work, and it makes it difficult for the caller to manage memory. – M.M May 07 '14 at 03:43

4 Answers4

6

When you say "created inside local scope" what you really mean is "an automatic variable." Automatic variables are automatically destroyed when the scope in which they are created is exited from.

But new does not create an automatic variable. It creates a dynamically allocated object, whose lifetime is not bound by the scope in which it's created.

The object created by, new A(sumA, sumB) is not a temporary.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
0

Values are returned from a local scope all the time. For example:

int f(int x)
{
    int y = x*x;
    return y;
}

While a variable would normally disappear when it falls out of scope, values returned from functions get special treatment by the compiler.

Regarding your example, you are creating an object on the heap and have a pointer to that object on the local stack. When your function returns the stack is cleaned up, that pointer along with it. Except - since you're returning the pointer to the caller, a copy of the pointer is passed back to the caller (probably through a cpu register).

As an aside: While this works fine, you need to be certain that the caller eventually deletes the returned object, else you'll have a memory leak.

jaket
  • 9,140
  • 2
  • 25
  • 44
  • So the object basically is not created with a scope right? because we still have access to the object through the pointer even if we have gone out of the function scope. – user3513507 May 07 '14 at 03:40
  • Right, the object is created on the heap. The pointer to it can still go out of scope though, such as might happen if you didn't return it, or the caller ignored the return value. – jaket May 07 '14 at 03:45
0

C++ does not automatically manage memory for you. This means you must manually 'delete' any objects created dynamically with the 'new' operator. Your code is valid, but I think it doesn't accomplish what you wish. I think you are looking for something like this:

A operator+(const A& that){
  int sumA = a + that.getA();
  int sumB = b + that.getB();
  return A(sumA, sumB);
}
jRobin
  • 11
  • 2
0

Yes, the value created with new will still be alive after the function exits.

As others have mentioned, it is necessary to delete these objects to avoid memory leaks.

Because of this, best general C++ practice is to not return bare pointers like this function does, but to return some sort of smart pointer object such as shared_ptr. That way, you can return a pointer to the newly created object, and the object will be automatically destroyed once there are no more active references to it.

JohnMcG
  • 8,709
  • 6
  • 42
  • 49