简体   繁体   中英

C++ loop stack allocation

While doing an assignment for a course and learning C++ while doing it, I was reading up on when to use stack allocation and dynamic allocation. I'm aware that in a lot of cases it is easier and better to use stack allocation. But there is a simple situation I'm puzzeled about.

Lets say you have a for loop:

for(int i = 0; i < 10; i++)
{
   MyObject obj(file);
   obj.doSomething();
}

Now the problem is that if the Object contains state, it keeps it state (stays the same object) while iterating through the iterations from 1 til 10. Maybe coming from a Java/C# background gets me on the wrong path. But I only see two ways of solving this:

  1. Using dynamic memory.
  2. Not giving file to the constructor but instead to the method doSomething(file) but this isn't very nice if you have more than one method manipulating the file object eg doSomethingElse(file) .

So what do you guys do in such a situation, or do you never get yourself in such a situation at all?

Update: Turns out i misunderstood and it is working as expected. Check the awnsers below! Thanks everyone

In the code you have posted, obj does not maintain any state between iterations.

for(int i = 0; i < 10; i++) 
{    
  MyObject obj(file); //obj enters scope, constructor is called with 'file'
  obj.doSomething(); 
}  //obj loses scope, destructor is called

In that example, obj is a different object every time. It may be using the same 'stack' memory location as the previous object, but the class destructor and constructor are called between iterations.

If you wish to have the object only be constructed once and used repeatedly, construct before the loop.

function(file)
{
    MyObject obj(file); //obj enters scope, constructor is called with 'file'

    for(int i = 0; i < 10; i++) 
    {    
      obj.doSomething(); //Same object used every iteration
    }  

}  //obj loses scope, destructor is called

In this code, obj is created (its constructor is called) each time through the loop when the line containing its declaration is reached and it is destroyed (its destructor is called) at the end of each loop iteration.

If you want it to be created once and have it save its state over loop iterations, declare it outside of the loop:

MyObject obj(file);
for (int i = 0; i < 10; i++)
{
    obj.doSomething();
}

If you need to have the same object used across multiple iterations like this and you need to change the state of the object during iteration (eg by changing the file), you will need to have some member function that allows you to change that state (either a dedicated member function like useThisFile(file) or an additional parameter to the member functions being used like doSomething(file) ).

Wouldn't the following still allocate your object on the surrounding stack and accomplish what you are after?

MyObject obj(file);
for (int i = 0; i < 10; i++)
{
  obj.doSomething();
}

In the code above, obj is created within the scope of a single iteration of the loop, and dies at its end. This is as if, in Java, you put MyObject obj = new MyObject() at the same location. No information will transition from one iteration of the loop to the other (unless you change the state of the file).

To convince yourself, place a function call as the "body" of the loop. In that function, create the variable on the stack. The variable will only live while this function is executing.

obj gets deallocated at the end of every iteration---its destructor is called ten times as well. As long as the class's destructor properly delete s anything created by the constructor, you'll be fine.

On an efficiency note, you might just want to declare obj once before entering the loop.

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