Sign in to follow this  

Runtime error with compile in VS2005, but not VS2002?

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

Ok, so i have some code for the main loop of my program. The main point of it is to provide a system to regester modules that should be updated every game loop. This include stuff like an Audio system, Resource loader, Main game loop, Input ... While they are running, the modules get an update call. If the window loses focus, they should become paused. These system level modules get cleared out at the end of the program. So, why does this NOT crash on my computer(VS2002), but DOES crash when compiled on another system (VS2005 express). The crash only occurs on exit (alt-f4 or the X) and only when not in the debugger. Although it is not multi-threaded, it is acting like there is a race condidtion between removing something, and pausing it.
bool WinFinish ( )
{	
	bool rVal = true;

	for ( vector<Module *>::iterator x = modules.begin(); x != modules.end(); x++ )
	{
		rVal &= (*x)->Destroy();
		delete (*x);
		modules.erase(x);
		x--;		//Crashes here.
		}
        return rVal;
        }

void  WinDoPause ( bool paused )
{
	for ( vector<Module *>::iterator x = modules.begin(); x != modules.end(); x++ )
	{
		(*x)->Pause(paused); //Or crashes here
		}
	}

These are the rutines where the system it gets called.
LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//..stuff...
	case WM_ACTIVATE:
		if ( pauseonfocus )
		{
			appPaused = (wParam == WA_INACTIVE);
			WinDoPause ( appPaused );
			}
		break;
//...
//Windows main loop
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
//blah...
WinFinish();
//blah...

Any advice on how to track down this bug? and why it only happens with the 2005 compiler?

Share this post


Link to post
Share on other sites
You should not call erase when iterating your vector.
Try to replace your code by:

bool WinFinish ( )
{
bool rVal = true;

for ( vector<Module *>::iterator x = modules.begin(); x != modules.end(); x++ )
{
rVal &= (*x)->Destroy();
delete (*x);
}
modules.clear();
return rVal;
}

Share this post


Link to post
Share on other sites
After you call erase, you can't use that iterator any more because it's invalid.
There are many possible fixes (not tested, but at least resembling a possible solution) :

vector<Module *>::iterator x = modules.begin();
while(x != modules.end())
{
rVal &= (*x)->Destroy();
delete (*x);
x = modules.erase(x);
}
vector<bool> Result;
transform(modules.begin(), modules.end(), back_inserter<bool>(Result), mem_fun<bool, Module *>(&Module::Destroy));
for_each(modules.begin(), modules.end(), mem_fun<void, Module *>(&Module::operator delete));
return find(Result.begin(), Result.end(), false) == Result.end();
And I'm sure many other ways. Since it's a vector, though, I'd suggest skipping the solutions that erase one element at a time as that will likely cause tons of extra and entirely unneccessary work to take place. kratolp's solution is probably one of the best, but if you're often deleting and/or adding elements to random places in the vector, you might want to consider using a different data structre such as list or set.

Share this post


Link to post
Share on other sites
Ok. So i made the change sugested by kratolp, but now the error is forced into
WinPause.
WinFinish is the only place any removals take place, and my AddTask function only does a push_back() onto the vector.
So I don't know how I can be losing a pointer or anything.
And again, it works both release and debug compiles on my computer, but not on my team-member's computer if he compiles it.
(distance is keeping me from just debugging on his computer. and I can't reproduce the error)

Extrarius? is the version you posted faster? or better in some way? or ammount to the same exact thing?

Share this post


Link to post
Share on other sites

This topic is 4302 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this