简体   繁体   中英

Is object created without new operator deleted in a specific case in C++

If we have the following code snippet:

MyObject my_object = MyObject(0);
my_object = MyObject(1);

What happens to MyObject(0)? Is it deleted? Looking at what I have read about it it should only be deleted when we leave the scope of creation, so the anwser is probably no. If this is the case is there any way to explicitly delete it other than using pointers?

MyObject my_object = MyObject(0);

This line creates my_object on the stack using MyObject 's constructor that can accept an int .

my_object = MyObject(1);

This line creates a temporary MyObject, again, using the same constructor as the first. This is then assigned to my_object by calling the assignment operator. If you didn't provide this operator then the compiler will make one for you that performs a shallow copy. When this statement completes, the temporary MyObject goes out of scope and the destructor for it is called.

When your my_object goes out of scope it is in turn destroyed in the same fashion. At no point do you need to manually delete this because everything is allocated on the stack.

There are two main regions in memory when talking about newly created objects: the stack and the heap. The heap contains all objects created dynamically with new. These objects need to be explicitly deleted with the delete operator. The stack is scope-specific and all objects defined on the stack will be deleted automatically. Since you don't use new, all your objects will be destroyed when their scope ends.

Assuming no compiler optimizations, your code roughly translates to:

{
   MyObject my_object;
   MyObject tempObject0(0);
   my_Object = tempObject0;
   MyObject tempObject1(1);
   my_Object = tempObject;
}//3 objects are deleted by this point (in theory)

Also note the difference between

MyObject myObject(0);

and

MyObject myObject = MyObject(0);

The second case creates a temporary object, so it will be less efficient. This all of course assuming no optimizations. Depending on the compiler, it might translate to the same thing.

1st line is creating an temp object and this object is assigned to my_object. In 2nd line, a temporary object is created and it is assigned to my_object.

So there is only one object my_object

We need not to think about temporay object. It is compiler responsibility to handle temporary object.

The term delete has a special meaning in C++, so the use of deleted is unfortunate.

MyObject my_object = MyObject(0);

This line declares that an object of type MyObject created with automatic storage duration (ie, on the stack). This object will be destructed (ie, its destructor will be executed) when the scope ends. No provision is made in the Standard for the recollection of the associated memory (see later example).

This object of type MyObject will be constructed using the expression MyObject(0) . This constructor will initialize the memory that has been set apart for its exclusive use.

Note: actually, a temporary could be created and the copy constructor then called, but most compiler eschew this intermediate step, thankfully, as the Standard specifically allows it.

my_object = MyObject(1);

This line assigns a new value, determined by the expression MyObject(1) , to the already existing my_object object. To do so, a temporary of type MyObject is created with automatic storage duration. Then, the assignment operator is executed; if not overloaded it will copy the state of the temporary into my_object , erasing what previous state was there. At the end of the expression, the temporary is destructed (once again, no provising is made for the recollection of the associated memory).

Note: MyObject(0) is not "deleted", as it does not exist, instead the memory it had written its state to is reused to copy the state from MyObject(1) .


As promised, since this seems your worry, a discussion on the memory aspects. This is compiler specific, but most compilers do behave similarly.

Suppose that we have the following function:

void f() {
  MyObject my_object = MyObject(0);

  {
    my_object = MyObject(1);
    do_something(my_object);
  }

  {
    my_object = MyObject(2);
    do_something(my_object);
  }
}

How much space does it require on the stack ?

  • We assume that it performs direct construction on the first line
  • We assume the compiler not smart enough to perform Stack Coloring (Clang does not, for example)

With those assumption, it requires the space for 3 MyObject .

  • MyObject my_object = MyObject(0); : my_object need live until the end of the function
  • my_object = MyObject(1); : a temporary need be created
  • my_object = MyObject(2); : a temporary need be created

The stack space is recollected at the end of the function execution.

If the compiler was smart enough to perform Stack Coloring, then the two temporaries (that are never needed together) could use the same memory spot, thus lowering the space requirement to 2 MyObject .

A smart optimizer could also, possibly, directly build MyObject(1) and MyObject(2) directly into my_object (if it can prove that the effects would be the same than building a temporary and then copying it), thus lowering the space requirement to 1 MyObject .

Finally, if the definition of do_something is visible, and it does not use its parameter, then under certain conditions it could (in theory) completely bypass the construction of my_object . Such optimizations can be witness with simple programs like:

int main() { int i = 0; for (; i < 1000; ++i); return i; }

which are trivially optimized to:

int main() { return 1000; }

(Note how i disappeared)

As you may notice... it's actually very hard to guess what the compiler/optimizer will be able to do. If you really have tight memory requirements, then (perhaps surprisingly), your best bet might be to replace the blocks by functions.

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