Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Memory management  (Read 9002 times)

0 Members and 2 Guests are viewing this topic.

ScArL3T

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Memory management
« Reply #15 on: August 23, 2015, 02:01:14 pm »
Thank you for the advice!

I cannot use the range-based for loop since the iterator must be updated. I tested this out, when I try to enter the PlayState for example, I get an error when the state is getting pushed back: Vector iterator not incrementable. The only way for this to work is to use:
for (auto i = 0; i < states.size(); i++)
Or:
for (auto it = states.begin(); it != states.end();  ++it )
EDIT: The second for loop gives the same error as the range-based. So the first for is the only one that's working.

Would you mind giving some context to this error? Because that's no supposed to happen.

It's strange  ??? . I got it working though.
I declared an iterator in my header file and after I push back a state inside the vector I reset the iterator like this:
states.push_back(std::move(state));
it = states.begin();

Then I can use this for without any errors:
for (it = states.begin(); it != states.end(); ++it)
{
        (*it)->update(window, dt);
}
???

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Memory management
« Reply #16 on: August 23, 2015, 02:04:13 pm »
I declared an iterator in my header file and after I push back a state inside the vector I reset the iterator like this:
Why do you declare an iterator in a header? Is it global? :o

Iterators are objects of extremely local scope. In most cases, it's an error to store them -- they're used for iteration, and they become invalid as the underlying container changes.

for (it = states.begin(); it != states.end(); ++it)
{
    (*it)->update(window, dt);
}
Don't do that! Declare the iterator locally, that is, inside the for loop.
Or use range-based for loops directly.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ScArL3T

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Memory management
« Reply #17 on: August 23, 2015, 02:12:16 pm »
I declared an iterator in my header file and after I push back a state inside the vector I reset the iterator like this:
Why do you declare an iterator in a header? Is it global? :o

Iterators are objects of extremely local scope. In most cases, it's an error to store them -- they're used for iteration, and they become invalid as the underlying container changes.

for (it = states.begin(); it != states.end(); ++it)
{
    (*it)->update(window, dt);
}
Don't do that! Declare the iterator locally, that is, inside the for loop.
Or use range-based for loops directly.

If I declare it locally (inside that method only) I get a vector iterator not incrementable error. The same goes for the range-based for loop.

I could get this to work without using an iterator like this:
for (unsigned int i = 0; i < states.size(); i++)
{
    states[i]->update(window, dt);
}

Or with the iterator, but it must be declared in the header file or in the cpp file outside of the methods because I have to reset it after I clear the vector and push_back another state:
states.push_back(std::move(state));
it = states.begin();

GraphicsWhale

  • Full Member
  • ***
  • Posts: 131
    • View Profile
Re: Memory management
« Reply #18 on: August 23, 2015, 02:37:10 pm »
Is your error compile-time or run-time? Are you trying to erase any elements while iterating?

Also, you shouldn't have to reset anything. The functions begin and end should be called in the for loop, not before-hand. Do NOT try to store iterators. Just one change to the vector can invalidate them. They also shouldn't be used to access elements unless you are iterating.
« Last Edit: August 23, 2015, 02:42:08 pm by GraphicsWhale »

ScArL3T

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Memory management
« Reply #19 on: August 23, 2015, 02:38:38 pm »
Is your error compile-time or run-time? Are you trying to erase any elements while iterating?

Run-time. I read about trying to erase elements while iterating gives an error. But all I do is clear the vector.  ???

Also, before iterating through the vector I check if it is empty or not:
if (!states.empty())
{
        for (it = states.begin(); it != states.end(); ++it)
        {
                (*it)->update(window, dt);
        }
}
« Last Edit: August 23, 2015, 02:43:35 pm by ScArL3T »

GraphicsWhale

  • Full Member
  • ***
  • Posts: 131
    • View Profile
Re: Memory management
« Reply #20 on: August 23, 2015, 02:46:33 pm »
Is your error compile-time or run-time? Are you trying to erase any elements while iterating?

Run-time. I read about trying to erase elements while iterating gives an error. But all I do is clear the vector.  ???

I edited my post to include more info, didn't think you'd respond so fast.

Please read this:
http://stackoverflow.com/questions/6438086/iterator-invalidation-rules

Iterators are "fragile" enough that they can be invalided by simply erasing an object. Why would you think clearing the entire vector wouldn't effect them?

EDIT: I see you have the same issue with response time as I did. Anyways:

1. You don't need to check before hand.
2. Is that the loop where you're getting the error?
« Last Edit: August 23, 2015, 02:50:06 pm by GraphicsWhale »

ScArL3T

  • Newbie
  • *
  • Posts: 32
    • View Profile
Re: Memory management
« Reply #21 on: August 23, 2015, 02:51:06 pm »
This would be a fast fix using this loop:
for (unsigned int i = 0; i < states.size(); i++)

Yes. The other loops are looking like the one above.