Is an object created without a 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 read about this, it should not be deleted until after we leave the scope, so anwser is probably not. If so, is there a way to explicitly remove it other than using pointers?

+6
source share
4 answers

The term delete has special meaning in C ++, so the use of remote failure.

 MyObject my_object = MyObject(0); 

This line declares an object of type MyObject created with automatic storage time (i.e., on the stack). This object will be destroyed (i.e., its destructor will be executed) upon completion of the area. The Standard does not provide any conditions for storing associated memory (see the following example).

This object of type MyObject will be constructed using the expression MyObject(0) . This constructor will initialize the memory that was allocated for its exclusive use.

Note: in fact, a temporary can be created and then the copy constructor is called, but most compilers avoid this intermediate step, fortunately, since the standard specifically allows it.

 my_object = MyObject(1); 

This line assigns the new value, defined by the expression MyObject(1) , to the existing my_object . To do this, a temporary type MyObject with automatic storage time is created. Then the assignment operator is executed; if it is not overloaded, it will copy the temporary state to my_object , deleting the old state. At the end of the expression, the temporary is destroyed (once again, no evidence is made to remember the associated memory).

Note: MyObject(0) not β€œdeleted” because it does not exist, instead of the memory in which it wrote its state, is reused to copy the state from MyObject(1) .


As promised, as this seems like your concern, a discussion of aspects of memory. This is compiler specific, but most compilers behave the same way.

Suppose 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 stack space is required?

  • Suppose it does a direct build on the first line
  • We assume that the compiler is not smart enough to do Stack Coloring (e.g. Clang is not working)

Under this assumption, space is required for 3 MyObject .

  • MyObject my_object = MyObject(0); : my_object needs to live until the end of the function
  • my_object = MyObject(1); : need to create a temporary need.
  • my_object = MyObject(2); : need to create a temporary need.

The stack space is remembered at the end of the function.

If the compiler is smart enough to do Stack Coloring, then two temporary files (which are never needed together) can use the same memory spot, thereby reducing the space requirement to 2 MyObject .

The smart optimizer can also possibly directly build MyObject(1) and MyObject(2) directly into my_object (if it can prove that the effects will be the same as creating a temporary one and then copying it later), thereby reducing the required space to 1 MyObject .

Finally, if the definition of do_something visible and does not use its parameter, then under certain conditions it (theoretically) could completely bypass the construction of my_object . Such optimizations can witness simple programs, such as:

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

which are trivially optimized for:

 int main() { return 1000; } 

(Notice how i disappeared)

As you can see ... it is actually very difficult to guess what the compiler / optimizer can do. If you really have strict memory requirements, then (perhaps surprisingly) the best option would be to replace the blocks by function.

+1
source
 MyObject my_object = MyObject(0); 

This line creates my_object on the stack using the MyObject constructor, which can take an int .

 my_object = MyObject(1); 

This line creates a temporary MyObject, again using the same constructor as the first. Then it is assigned to my_object , invoking the assignment operator. If you did not provide this operator, then the compiler will make one for you, which 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, in turn, is destroyed in the same way. In no case do you need to manually delete this, because everything is allocated on the stack.

+5
source

There are two main regions in memory when it comes to newly created objects: stack and heap. The heap contains all objects created dynamically with new ones. These objects must be explicitly deleted using the delete operator. The stack is area-specific, and all objects defined on the stack will be deleted automatically. Since you are not using a new one, all of your objects will be destroyed when their scope expires.

Assuming the optimizer is not optimized, 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, of course, does not imply any optimizations. Depending on the compiler, this may translate to the same thing.

+2
source

The first line creates a temporary object, and this object is assigned to my_object. On line 2, a temporary object is created and my_object is assigned.

So there is only one my_object

We do not need to think about a temporary object. The responsibility for handling the temporary object lies with the compiler.

+1
source

Source: https://habr.com/ru/post/896459/


All Articles