Jump to content
  • Advertisement
Sign in to follow this  
simon10k

What would cause a standard seq container to crash?

This topic is 4825 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'll post my code later. I created an enemy class which is pretty much identical to my laser class which works. But the enemy class crashes my comp when I remove elements from it. Its a fullscreen game so it is difficult to debug. On crash the values of x and y are undefined of the Enemy that got hit by a laser which is when the enemy is removed for the EnemyList. I have a constructor but not a destructor because the Enemy class only has x,y data and does not allocate anything. It is really annoying because I have to turn the power off mycomp to restart most of the time. My code goes something like this (it is on my other comp)... CEnemy *Enemy = new CEnemy(x, y); EnemyList.push_back(*Enemy); And when the time comes to remove an Enemy I've tried pop_front, pop_back and erase. But they all cause the same problem, I've also made sure that I'm not removing elements that does exist. Edit: Here is my code... enemy.h
#pragma once
#include <list>
#include "graphics.h"
#include "laser.h"

class CEnemy {
	int x, y;	
public:
	CEnemy(int set_x, int set_y): x(set_x), y(set_y){}
	int GetX() { return x; }
	int GetY() { return y; }	
};

class CEnemyList
{
	CAnimation anim;
	std::list<CEnemy> EnemyList;
public:
	CEnemyList(char* bitmap):anim(bitmap, 32, 32, 100){}
	bool Collision(RECT*);
	void AddEnemy(int x, int y);
	void Draw();
	void LaserDamage(CLaserGun*);
};

enemy.cpp
#include ".\enemy.h"

bool CEnemyList::Collision(RECT* rect)
{
	std::list<CEnemy>::iterator iter;

	for(iter = EnemyList.begin(); iter != EnemyList.end(); ++iter)
	{
		if(rect->left < iter->GetX()+32)
			if(rect->right > iter->GetX())
				if(rect->top < iter->GetY() + 32)
					if(rect->bottom > iter->GetY())
						return true;
	}

	return false;
}

void CEnemyList::AddEnemy(int x, int y)
{
	CEnemy *Enemy = new CEnemy(x, y);
	EnemyList.push_back(*Enemy);
}

void CEnemyList::LaserDamage(CLaserGun* LaserGun)
{
	std::list<CEnemy>::iterator iter;

	for(iter = EnemyList.begin(); iter != EnemyList.end(); iter++)
	{
		int x = iter->GetX();
		int y = iter->GetY();
		RECT rect = { x, y, x+32, y+32 };

		if(LaserGun->Collision(&rect))
			EnemyList.pop_front();			
	}
}

void CEnemyList::Draw()
{
	std::list<CEnemy>::iterator iter;

	for(iter = EnemyList.begin(); iter != EnemyList.end(); ++iter)
		anim.Draw(0, anim.GetNumOfFrames()-1, iter->GetX(), iter->GetY());
}

Share this post


Link to post
Share on other sites
Advertisement
I see two problems.

1:
Quote:

CEnemy *Enemy = new CEnemy(x, y);
EnemyList.push_back(*Enemy);

This code is leaking memory. As you are creating a new enemy dynamically, then creating a copy of this instance on to the stack. All the enemies on the heap are being lost.

This could should be ...
CEnemy enemy(x, y);
EnemyList.push_back(enemy);

Or if you need multiple enemy types then you would want to use pointers ...

CEnemy *pEnemy = new CEnemy(x, y);
EnemyPointers.push_back(pEnemy);

However, you should not dynamically store the enemies unless you are using polymorphism.

2:
Quote:


void CEnemyList::LaserDamage(CLaserGun* LaserGun)
{
std::list<CEnemy>::iterator iter;

for(iter = EnemyList.begin(); iter != EnemyList.end(); iter++)
{
int x = iter->GetX();
int y = iter->GetY();
RECT rect = { x, y, x+32, y+32 };

if(LaserGun->Collision(&rect))
EnemyList.pop_front();
}
}


This is what is crashing your progarm. Popping the front is not removing the current element, same with popping the back. Unless they are the current element.

This should do the trick ...

void CEnemyList::LaserDamage(const CLaserFun *const LaserGun)
{
std::list<CEnemy>::iterator itr = EnemyList.begin();
while (itr != EnemyList.end())
{
int x = itr->getX();
int y = itr->getY();
RECT rect = { x, y, x + 32, y + 32 };
if (LaserGun->Collision(&rect))
{
itr = EnemyList.erase(itr);
}
else
{
itr++;
}
}





The erase function returns the next element in the list after the one that was erased.

I hope this helped / fixed your problem! :)

Share this post


Link to post
Share on other sites
Quote:

CEnemy *Enemy = new CEnemy(x, y);
EnemyList.push_back(*Enemy);


Memory leak!!

Quote:
if(LaserGun->Collision(&rect))
EnemyList.pop_front();


If the iterator is currently pointing to the front of the list, you're in deep doo-doo.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!