Problem with vectors, or inheritance maybe? I dunno.

Started by
8 comments, last by Svenjamin 17 years, 6 months ago
Hey Everybody, I am having a problem in my current game. I have been trying to fix it for about two weeks using google, my books, and this site, but I had not posted it here because the problem is so vague it seems. Anyways, I have a class, cEnemyShip which is a base class for three different types of enemy ship, cDrone, cClaw, and cViper. I have a cEnemyManager class that has a vector of pointers to cEnemyShips. The enemy manager has functions that go through every item in the vector and update it and check for collisions. This seemed to work when there was only one ship in the vector when I first tried it out, but when I added a second ship, I ran into problems. The player is a spaceship and can fire lasers at the enemies. But if a laser hits an enemy ship (not neccessarily killing it) other than the last one on the vector, the game crashes. so in order to make the game not crash, I would have to shoot the second ship created until its dead, then shoot the first. I apologize for not being able to post source, my PC does not have internet access. I think I have explained everything, but ask if you have questions. I greatly appreciate any help given. Thank you, Svenjamin
Advertisement
1. 'It crashes' is not a valid problem description. Use your debugger and find out what is the actual root cause of the crash.

2. Narrow down your problem. Try working with a single hard-coded ship rather than a vector of ships and see if you still experience problems.

3. Check your usage of the vector. My initial guess would be that you're modifying it while you're still iterating over it.
Thanks for the quick reply,
1) I'm sorry, I should have been more specific. The game crashes when something tries to call an accessor method of a cMovingObject (which is the base class for all other game objects) which presumably has been deleted or somehow lost. Its difficult to tell which object (laser or ship) is calling the method, because the debugger takes me to the class listing. (I'll take any tips on using visual studios debugger if you have them, I don't know that much about it except how to step through programs and use breakpoints)
I thought it might be a problem with copying objects or something, so I put in copy constructors and overloaded=operators, but it didn't help, of course I could have implemented them incorrectly.

2) I was working with hard coded ships before I built the enemy manager and it worked just fine.

3)I am modifying the vector when something needs to be destroyed, but I have done so before, so why wouldn't it work now?
Heres what I'm doing:
for (unsigned int i=0; i<m_Ships.size(); i++)
{
// Update stuff, if something needs to be deleted...
delete m_Ships;
m_Ships = NULL;
m_Ships.erase(m_Ships.begin() + i);
i--;
}

I do the same thing for lasers, each ship (including the players) has a vector in which it stores pointers to lasers.

Thanks,
Svenjamin
I'd check how your accessor method gets the vector. if it is copy constructed, you delete the object, but the pointer value remains in the copy. Your delete looks allright.
Quote:Original post by Svenjamin
(I'll take any tips on using visual studios debugger if you have them, I don't know that much about it except how to step through programs and use breakpoints)


This is a great place to start.
once u remove something like that the whole vector becomes invalid, so u cant iterate over them any more, if u do it (hopefully) should crash

the best (+ fastest) method is to just mark the ship dead + then after youve updated all the ships remove all the dead ones in one go
something like (check the syntax)
A.erase( remove_if( A.begin(), A.end(), mem_fun_ref( &remove_func ), A.end() );



i'd agree if he was keeping iterators. But he's referencing indexes and begin() which should be valid.
Thanks for the replies,
The accessor methods for the vectors all look like this:
std::vector<cLaser*> &cShip::GetLasers()
{
std::vector<cLaser*> &Lasers = m_Lasers;
return Lasers;
}

I think I am remembering that correctly, however, the accessor method which causes the problem is not one of these that returns a reference to a vector, it is a method that returns an integer, very simple.

I will try just flagging ships and lasers as dead or not dead and deleting them all at once accordingly and see if that works.
Thanks again,
Svenjamin
I think it wouldn't be a bad idea to create a handle class rather than dealing with the pointers directly. This shifts the responsibility of pointer deletion to the handle, and you can do reference counting if you need to have multiple pointers to the same object. I personally have never done reference counting before, but I have used handle classes to encapsulate pointers to polymorphic types, and it works quite well. If nothing else, you won't have to worry about when to delete your pointers so much.

I couldn't say for sure if this would fix your problem, but I'm willing to bet it's related to your use of pointers.
Thanks everybody for the help, Giving each object a dead/alive flag and deleting the dead objects accordingly worked.
Thanks Again,
Svenjamin

This topic is closed to new replies.

Advertisement