Archived

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

Deleting an inherited object crashes my game. Need help

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

I have a particle system which consists of a particle system manager (PSManager) class that manages (renders, adds, deletes, etc) particle emitters (ParticleSystem class). That works fine. The problem is that when deleting a child of the ParticleSystem, the game crashes. The removeSystem which belongs to PSManager looks like this:
// Method to remove a particle system
void PSManager::removeSystem (ParticleSystem* sys)
{
	bool found = false;
	std::vector <ParticleSystem*>::iterator count;

	count = systems.begin();
	while (count != systems.end() && !found)
	{
		if (sys == (*count))
		{
			found = true;
			delete sys;
			sys = NULL;
			count = systems.erase (count);
		}
		else ++count;
	}

} // End of method removeSystem
The ParticleSystem and the child of the ParticleSystem (Explosion) classes look like this:
// Particle system class
class ParticleSystem
{
	public:

		Particle* particles;
		int type;					// Type of particle system. 0 = ship, 1 = bullet, 2 = explosion
		float slowdown;				// Slow down particles
		float x_speed, y_speed;		// Base X/Y speeds of new particles
		float new_x, new_y;			// Positions of new particles
		float zoom;
		int num_particles;
		bool regenerate;			// True if regenerating particles forever, false if not

		ParticleSystem (int n, int typ);		// Constructor (no. of particles, type)
		ParticleSystem (int n);					// Constructor for explosions
		virtual void initialiseParticles (float red, float green, float blue);
		void drawParticles (bool rejuvinate);
		void setNewSpeed (float x, float y);
		void setPosition (float x, float y);
		void initExplosion (float x_pos, float y_pos);
		virtual ~ParticleSystem();
};
// Explosion class
class Explosion : public ParticleSystem
{
	public:

		Explosion (int num);										// Constructor
		~Explosion();												// Destructor
		void initialiseParticles (float x_pos, float y_pos/*float red, float green, float blue*/);
};
I suspect it might be because removeSystem() accepts a pointer to a ParticleSystem rather than an Explosion but I thought this wouldn''t be a problem as Explosion inherits from Particle System. Can anyone help?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
His base class destructor is virtual, and so his derived class is also implicitly virtual.

I cant see a problem in the code (apart from the class design). The remove loop looks ok, assuming the object was allocated onto the free store.

Share this post


Link to post
Share on other sites
I don't know which line it is crashing on. I'll try to have a look.

// Destructor

ParticleSystem::~ParticleSystem()
{
delete [] particles; // Delete particles array

}


// Destructor

Explosion::~Explosion()
{
delete [] particles;
}


[edited by - Billy Lee on November 11, 2003 12:16:30 PM]

[edited by - Billy Lee on November 11, 2003 12:16:59 PM]

Share this post


Link to post
Share on other sites
Your local helpful debugger will be more than happy to show you what line it's crashing on pretty quickly.

I can think of one thing, given the information available, that could crash the program.

Explosion is derived from ParticleSystem, yes? So, the destruction sequence goes like this:


Explosion::~Explosion ();
ParticleSystem::~ParticleSystem();
// and both destructors do this:

delete [] particles;
// So it effectively does this:

delete [] particles;
delete [] particles;


Attempting to delete things twice is a sure way to send you straight the pit of eternal crashing.

For a start, initialize all pointers to NULL or 0, and always set your pointer to NULL, or 0, after you delete. Deleting a null pointer is not an error, so nothing will happen, even if you do try to delete it again.

The second thing to do is to let ParticleSystem look after it's own data members. Explosion has no business trying delete 'particles'. It'll do well enough if it keeps it's own data members in order. As an added bonus, any more classes that derive from ParticleSystem can rest safe in the knowledge that they needn't worry about clearing up after ParticleSystem, and any fixes to the deletion of particels in ~ParticleSystem (such as the additon of the line 'particles = NULL;') is automatically applied to all derived classes. By magic, no less.


// Helpful, or confusing macros, depending on your point of

// view

// Note the need to remember to use safe_delete_array

// instead of safe_delete. But you would need to remember to

// use [] anyway.

#define safe_delete(pointer) delete pointer; pointer = NULL;
#define safe_delete_array(pointer) delete [] pointer; pointer = NULL;



Ro_Akira


[edited by - Ro_Akira on November 11, 2003 12:39:59 PM]

[edited by - Ro_Akira on November 11, 2003 12:41:58 PM]

Share this post


Link to post
Share on other sites
quote:

I agree with Ro_Akira about the problem, but the "safe_delete" will only mask it. Solve it using the RAII idiom.



And I agree that in general, one should try and avoid using raw allocations and deallocations and use things like stl::vector and what not.

If/When you do use delete though, safe_delete is just handy.

Ro_Akira

Share this post


Link to post
Share on other sites
Thanks Ro_Akira, you were right. I was trying to delete Explosion twice and that''s what caused the problem. I just removed the delete [] particles line out of the Explosion destructor and it worked! It''s always the one line errors that cause the the biggest problems!

Share this post


Link to post
Share on other sites