Archived

This topic is now archived and is closed to further replies.

STL-error?

This topic is 5304 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

Hi, Anyone has a clue how this code can give an Access Violation error (you know: 0xC0000005)? Here's a simplified version:
typedef std::list<int> PositionList;
PositionList _trail;

// some actions on list...


if(_trail.size() >= 2)
{
  // for every two points that follow

  PositionList::const_iterator t1 = ++_trail.begin();  // invalid access crash here

  PositionList::const_iterator t2 = _trail.begin(); 
  PositionList::const_iterator one_before_end = --_trail.end();
  for(; t1 != one_before_end; ++t1, ++t2)
  {
    // a line is drawn between points 

    // nothing dangerous

  }
}
It crashes when trying to increment the iterator. The only reason I can think of a crash there is when the list doesn't have the required number of elements. But even after adding an extra check like this does the crash happen (also in the increment):
if(_trail.size() >= 2)
{
  // for every two points that follow to one before last

  PositionList::iterator t1 = _trail.begin();    
  if(t1 != _trail.end())    
    ++t1;
  else
    log << "Ack!";

  PositionList::const_iterator t2 = _trail.begin(); 
  PositionList::const_iterator one_before_end = --_trail.end();
  // rest...
Anybody help? [edited by - Jedyte on June 3, 2003 5:14:47 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
ummm try ++(_trail.begin());
The way you have it now is being evaulated as:
(++_trail).begin();
which obviously is not what you want.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
ummm try ++(_trail.begin());
The way you have it now is being evaulated as:
(++_trail).begin();
which obviously is not what you want.

If It was evaluated like that then the compiler would probably complain. Furthermore if you check the second version my code is
PositionList::iterator t1 = _trail.begin();
++t1;
and that still crashes too, so that can''t be it. Thanks anyway.

Share this post


Link to post
Share on other sites
Umm, I dont think you can change the position of the begin() iterator. It always points to the beginning, thats what its there for.

I think you are looking for:
PositionList::const_iterator t1 = _trail.begin() + 1; 

or
PositionList::const_iterator t1 = _trail.begin();
++t1;

Share this post


Link to post
Share on other sites
quote:
Original post by Jambolo
Since nothing is wrong with the code you posted, the source of the problem is likely to be here:


// some actions on list...


Find out exactly which pointer is broken and then find out how it got broken.



Hmm yeah I was afraid of that. It seems unplausible cause I never had errors there before, it was only after rewriting that that the error occured. Then again, you never now with pointer errors...

Share this post


Link to post
Share on other sites
quote:
Original post by petewood
quote:
Jedyte Then again, you never now with pointer errors...


You don't have any pointers


I know, that's what boggles me the most. But I do in other parts of the program, so I don't see any other possibility then that they have to be the culprit.

The closest pointers being used are the projectiles themselves... You see this list is part of a Projectile, which keeps different positions for a particle-like helix structure. Each time you shoot a Projectile it is allocated and put into a list (and each Projectile in this list of pointers, has itself this trail list of positions) until it dies.

I can't post a bigger example like you suggested, because the conditions that trigger these parts of the code rely on much more code (collision of projectiles in maps with blocks, enemies, ...) and I would drown you all in code

[edited by - Jedyte on June 4, 2003 6:55:23 AM]

Share this post


Link to post
Share on other sites
I would agree with separating out the whole begin() and ++ stuff though. Putting it all on one line doesn''t gain you anything and makes debugging harder.

After the "// some actions on list" bit and before the if and loop that follows it in your example, do something simple that operates on the whole list. eg. a for_each with a function pointer that takes an integer. If that crashes too, it proves that you broke something earlier. Then wrap that little test into a function and use it in an assert to check at various points in your code that the list is still intact. That way you can easily narrow down where you break it.

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

Share this post


Link to post
Share on other sites
Hmm, I think something's wrong in the destructor of the class.
Could it be that because I don't have an (empty) virtual destructor in a derived class, that it gives the error? In what cases is a virtual destructor needed when using polymorphism?

[edited by - Jedyte on June 4, 2003 1:03:15 PM]

Share this post


Link to post
Share on other sites
Usually always. Certainly any time those instances might be deleted via a pointer to a base class.

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

Share this post


Link to post
Share on other sites
Got it! Thanks Kylotan, your idea brought me back on track.
It was a stupid list::back() when the list was empty. Cheez, I've been programming in STL for over 4 years, you'd think I'd wouldn't make such a mistake anymore %)

To return to my other question now that we're on it, if I write this, will the destructors be called correctly?

class Base
{
Base();
virtual ~Base(); // virtual here

};

class Derived: public Base
{
Derived();
// but nothing here, we don't need it

};
Thanks.

[edited by - Jedyte on June 4, 2003 1:33:20 PM]

Share this post


Link to post
Share on other sites