Jump to content
  • Advertisement
Sign in to follow this  
Red Ant

std::list ... (Not so) Funny access violation

This topic is 4910 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I've got a class GUI_TimerComponent (all irrelevant content stripped out)
class GUI_TimerComponent
{
public:
    virtual ~GUI_TimerComponent();

    
protected:
    GUI_TimerComponent();

private:
    typedef std::list < GUI_TimerComponent* > InstanceList;

    static InstanceList smv_InstanceList;

};


Any TimerComponent must add a pointer to itself to the static smv_InstanceList. This is done in the c'tor (naturally). When an instance is destroyed, it's the d'tor's responsibility to find that instance's entry in the list and erase the entry.
GUI_TimerComponent::InstanceList GUI_TimerComponent::smv_InstanceList;



GUI_TimerComponent::GUI_TimerComponent()  
{
    // Register this instance in our global instance list.
    smv_InstanceList.push_back( this );
}

GUI_TimerComponent::~GUI_TimerComponent()  
{
    // Kill all timers.
    TimerList::const_iterator itEnd = mv_ListOfTimers.end();
    TimerList::iterator itCur;

    for ( itCur = mv_ListOfTimers.begin(); itCur != itEnd; ++itCur )
    {
        KillTimer( 0, ( *itCur ).t_nTimerId );
        ( *itCur ).t_nTimerId = 0;
    }

    // Unregister from the global instance list.
    // Find the instance to which the specified timer belongs.
    InstanceList::const_iterator itInstanceEnd = smv_InstanceList.end();
    InstanceList::iterator itInstanceCur;

    for ( itInstanceCur = smv_InstanceList.begin(); itInstanceCur != itInstanceEnd; ++itInstanceCur )
    {
        if ( *itInstanceCur == this ) // <----- Here I get an access violation.
        {
            smv_InstanceList.erase( itInstanceCur ); 
        }
    }
}




For some reason the d'tor always dies with the following message: Unhandled exception at 0x00446a3d in ASTS_TakeTwo.exe: 0xC0000005: Access violation reading location 0xfeeefef6. Anyone see any obvious mistakes I'm making?

Share this post


Link to post
Share on other sites
Advertisement
If I recall well any iterator is invalidated as soon as you do something like erase to change the list. So the last loop in your coding will go amiss, because after the first call to erase the iterator is no longer valid. Use a for-loop instead for such operations.

Greetz,

Illco

Share this post


Link to post
Share on other sites
You're a genius! =) That solved it. I should have added a break after erasing the element anyway, seeing as the entry can only be contained in the list once anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by Illco
If I recall well any iterator is invalidated as soon as you do something like erase to change the list. So the last loop in your coding will go amiss, because after the first call to erase the iterator is no longer valid. Use a for-loop instead for such operations.

Greetz,

Illco


Not exactly, only iterators pointing to the element being erased are invalidated (hence his access violation). Erase returns the iterator after the point of erasure, but as he only has a single entry in the list, he just needs to break out of the loop.

Share this post


Link to post
Share on other sites
Ah great -- I already had a hunch there had to be something there. So the right way of removing some elements, for example conditionally would be something like the following piece of code?


std::vector<int> vInts;
std::vector<int>::iterator iInt = vInts.begin();

while( iInt != vInts.end() )
{
if ( some_condition_holds )
iInt = vInts.erase( iInt );
else
iInt++;
}


Thanks for the PM btw. I'll think about it. Hehe. Greetz,

Illco

Share this post


Link to post
Share on other sites
Yes, however, vectors are not like lists. In a vector, all iterators after the point of erasure are invalidated.

But your code is correct.

Share this post


Link to post
Share on other sites
Ok that explains where my idea came from. I use vectors often and lists almost never, but I for some reason thought the iterators would behave similarly. Thanks.

Greetz,

Illco

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!