Jump to content
  • Advertisement
Sign in to follow this  
DaveBifti

Help with an assertion error using vectors

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

Hi, new to forums, reletively new to coding... I'm making a small game, involving monsters and my player, i have a vector of monsters that each have co-ordinates. My player moves around a virtual grid and when my player lands on a grid co-ordinate wich contains a monster i.e has the same co-ordinats, the monster is deleted from the vector. Now thus far, the assertion error seems to be random, here's my source where i think the assertion error is caused

for(int k = 0; k <= gameSettings.numMonsters; k++){
					if(myPlayer.getPosRow() == monsterVector[k].getPosRow() && myPlayer.getPosColumn() == monsterVector[k].getPosColumn()){
						monsterVector.erase(monsterIter+k);
						gameGrid[myPlayer.getPosRow()][myPlayer.getPosColumn()] = CLEAR;
						gameSettings.numMonsters--;
						cout << "Found monster and killed it!\n";
						for(int i = 0; i <= gameSettings.numMonsters; i++){
							cout << "Monster " << i+1 << " position: ";
							monsterVector.displayPos();
						}
					}
				}


The error: Debug Assertion failed Expression("this->_Has_Container()",0) for information etc etc...... abort retry ignore... any ideas? as i said it's fairly random but has a tendency to happen when the number of monsters reaches 2 or 3. When i break, the compiler takes my to the vector template at this function
_Myt& operator+=(difference_type _Off)
		{	// increment by integer
                _SCL_SECURE_VALIDATE(this->_Has_container());  /*Points to this line*/
		_SCL_SECURE_VALIDATE_RANGE(
			_Myptr + _Off <= ((_Myvec *)(this->_Getmycont()))->_Mylast &&
			_Myptr + _Off >= ((_Myvec *)(this->_Getmycont()))->_Myfirst);
		_Myptr += _Off;
		return (*this);
		}

Share this post


Link to post
Share on other sites
Advertisement
Quote:

for(int i = 0; i <= gameSettings.numMonsters; i++){
cout << "Monster " << i+1 << " position: ";
monsterVector.displayPos();
}

This looks suspicious to me. If numMonsters is greater than monsterVector.size(), you'll have problems. Why do you need to track the number of monsters when you can just look at the size of your monster vector? Storing this value separately seems to me like it only adds more things to go wrong.

Also,
Quote:

monsterVector.erase(monsterIter+k);


What is monsterIter? You're not holding on to an iterator into your vector somewhere, are you? Iterators easily become invalidated (say, by calling erase() on the container), so you shouldn't be storing them. And if you have an iterator into your container, why aren't you using that to loop over all the vector elements?

A few other things, now that I think about it:
-Your loop will skip over some monsters as it is currently written. Consider, you have 4 monsters, the second gets removed:
When k = 1, remove monster at index 1.
This will shift everything else in the array down, so the monster at index 2 is now at index 1, etc.
Increment k. k = 2 now, so the monster at index 1 (which was at index 2 prior to this loop iteration) will get skipped over.

-Why do you print the location of every monster every time one gets erased?

Share this post


Link to post
Share on other sites
i was getting errors with the .size() member function i can't remember the exact content, may have been the same assertion error... tracking in this way should give me the exact size of the vector though?

ok i'll take it out, its only used to print the monster positions so i could test, rather than spend ages looking for the monsters, ill test some more now.

[edit] monsterIter is my vector iterator...

vector<Monster>::iterator monsterIter = monsterVector.begin();

can you elaborate on using the iterator to loop through my elements?

Share this post


Link to post
Share on other sites
this happens when you try to randomly access([]) past the size of the vector,if you can't know the exact number of monsters before starting to fill the vector, you have to use push_back(), or check against Vector.size() before you access that position in the vector, ie.

for(int i = 0; i < SomeNumber;i++)
{
if(i < List.size())
List = whatever;
}
if you know the number of monsters, then resize() the vector before you fill it, this option performs better because it cuts down on the amount of dynamic memory allocation involved.


Share this post


Link to post
Share on other sites
ok all the monsters positions are printed after 1 is erased to give help to me for testing, as oppsosed to aimlessly navigating around my grid trying to find the monsters and kill them as all the monsters(10 in total) are randomly positioned at start.

[edit]

so if i store the index position in a variable while the for loop is iterating, then when the loop exits, use erase() with the iterator and index variable instead.

Share this post


Link to post
Share on other sites
Managed to fix it, you put me on the right track. i've split the code up a little, it may have been something to do with how i was erasing the first and last elements, i'm not too sure but what i have here rectified the problem although its a little messy at the moment...


for(int k = 0; k < monsterVector.size(); k++){
if(myPlayer.getPosRow() == monsterVector[k].getPosRow() && myPlayer.getPosColumn() == monsterVector[k].getPosColumn()){
indexPos = k;
eraseMonster = true;
}
}




if(eraseMonster == true){
if(indexPos == monsterVector.size()){
monsterVector.pop_back();
}
else if(indexPos == 0){
monsterVector.erase(monsterVector.begin());
}
else{
monsterVector.erase(monsterIter+indexPos);
}
gameGrid[myPlayer.getPosRow()][myPlayer.getPosColumn()] = CLEAR;
gameSettings.numMonsters--;
cout << "Found monster and killed it!\n";

for(int i = 0; i < monsterVector.size(); i++){
cout << "Monster " << i+1 << " position: ";
monsterVector.displayPos();
}
eraseMonster = false;
}


Share this post


Link to post
Share on other sites
The STL already provides perfectly fine algorithms for removing elements that satisfy a predicate from a range. Untested code:

#include <algorithm>

bool collides(const Monster& m)
{
return myPlayer.getPosRow () == m.getPosRow ()
&& myPlayer.getPosColumn() == m.getPosColumn();
}

// somewhere in your code where you want to delete collided monsters
monsterVector.erase(std::remove_if(monsterVector.begin(), monsterVector.end(), collides),
monsterVector.end());


[Edited by - DevFred on December 2, 2008 1:16:45 PM]

Share this post


Link to post
Share on other sites
i've tested and is working fine, i thought it wasn't as i hadn't printed any statement verifying a hit or checking the monsterVector in debug at first lol.

very handy indeed, thank you!!

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!