Unhandled Exception When Using a List

Started by
6 comments, last by sarim 11 years, 2 months ago

I started work on a pong game just to get back into game programming since it's been a while for me. Everything was working fine until I came about my current problem. I have an Entity Manager class that handles iterating through a list of entities within the game (paddles and ball) and rendering them. The program runs fine, however when I end it an Unhandled Exception pops up concerning the Release() of the texture the paddle has. The interesting thing is that if I run the program without the list and render the paddle manually, it works fine without the error. Hopefully someone knows what I'm doing wrong? Also after seeing the code if you have any suggestions on how I can make something cleaner or more efficient I would love to hear it smile.png

EntityManager.h


#ifndef ENTITYMANAGER
#define ENTITYMANAGER

#include "Globals.h"
#include "Entity.h"
#include <list>

class EntityManager
{

public:

	void Add( Entity &entity );

	void Update( LPD3DXSPRITE sprite );

private:

	std::list<Entity>           entities;
	std::list<Entity>::iterator iter;
};

#endif  ENTITYMANAGER

EntityManager.cpp


#include "EntityManager.h"

void EntityManager::Add( Entity &entity )
{
	entities.push_back( entity );
}

void EntityManager::Update( LPD3DXSPRITE sprite )
{
	iter = entities.begin();

	while ( iter != entities.end() )
	{
		sprite -> Draw( iter -> GetTexture(), NULL, NULL, iter -> GetPosition(), White );

		iter++;
	}
}

Game.h


#ifndef GAME_H
#define GAME_H

#include "Globals.h"
#include "DxManager.h"
#include "Entity.h"
#include "EntityManager.h"

class Game
{

public:

	bool Init( HWND &window );
	void Run();

private:

	HWND window;

	DxManager GManager;
	Entity    LeftPaddle;
	//Entity    RightPaddle;
	//Entity    Ball;

	EntityManager EManager;
};

#endif  GAME_H

Game.cpp


#include "Game.h"

bool Game::Init( HWND &window )
{
	this -> window = window;

	if ( !GManager.InitD3D( this -> window ) )
	{
		GameOver = true;
		return false;
	}

	LeftPaddle.LoadTexture( GManager.GetDevice(), "Resources/LeftPaddle.png" );

	EManager.Add( LeftPaddle );

	return true;
}

void Game::Run()
{
	GManager.Begin();
	
	EManager.Update( GManager.GetSprite() );

	//GManager.GetSprite() -> Draw( LeftPaddle.GetTexture(), NULL, NULL, LeftPaddle.GetPosition(), White ); * program runs fine if i use this line instead of EManager.Update( GManager.GetSprite() ); *

	GManager.End();
}

Error


First-chance exception at 0x000F14AA in Pong.exe: 0xC0000005: Access violation reading location 0xFEEEFEF6.
Unhandled exception at 0x000F14AA in Pong.exe: 0xC0000005: Access violation reading location 0xFEEEFEF6.

Advertisement

The reason for the exception looks quite straightforward.

The destructor for EntityManager class is getting invoked while your update is still in process.

So you need to release the resources before your destructor gets invoked.

Common practice is to actually release the resources within the destructor.

Another practice, which is good to follow, is to have a start and stop thread mechanism, bonded with your renderer's constructor and destructor, respectively.

This way, you can ensure that the update run is not occurring while destruction of resources is in progress.

Are you talking about releasing the resources with the destructor of the actual entity object? If so then you should know that it's what I'm already doing. However the program stops at the beginning of the entities destructor and throws the unhandled exception, so I'm not sure if its the destructor of the entity manager causing the problem?

We don't have all of your code, and I suspect the cause for your problem exists in the code we can't see.

However, I have run into similar situations as this. Your Entity is loading a resource (texture) that is provided by the GManager that manages DX resources. Both GManager and EntityManager are part of Game. It is likely that when an Entity is destroyed, it has to release whatever texture it has, and that GManager needs to be in a valid state in order to handle this resource release. But what happens if, when the Game object is destroyed, GManager is destroyed before EManager is? In this case, when EntityManager is destroyed (along with whatever Entity objects are contained in its list) then those Entity objects will be trying to release resources through GManager, but GManager has been destroyed already, so any internal state and methods called to release the resource will raise an exception.

That sounds like it may actually be the problem. How do you think I should structure the code to eliminate this problem?

Clear your entity list before Game destructor is called. Any assets that rely on GManager to be released should already be destroyed by the time Game, and thus GManager, are destroyed.

Alternatively, you could restructure your objects to guarantee an explicit order of destruction. If GManager and EManager are explicitly new-ed in your Game constructor, they can be explicitly deleted (either through delete, or through calling reset() if they are stored in a unique or shared ptr). This way, you can guarantee that EManager is deleted first.

Thanks I'll try your advice when I get on and work on it... I'll let you know what happens
So I tried doing what you said and created 'new' pointer objects in the constructor of Game and delete them in the destructor, however the result is the same. When the program ends the exception still occurs

This topic is closed to new replies.

Advertisement