Question:
C++ Removing vector element causes crash?
?
2012-08-19 15:38:57 UTC
Okay, so, I have a vector for storing objects in a game. Whenever an object gets destroyed, I need to remove it from the vector. What I have now will run for a bit, then crash the program.
(I have 2 vectors, one for objects, one for particles, I'll just show the particles since deleting is done in practically the same way)
What I have:

base.h:

class p_tem{
...
};

//par_sys is a pointer to the main vector that contains all of the particles
//oid is the index in the vector that the particle is
bool p_tem::onstep(vector *par_sys, int oid){
bool erased=false;
...
...
this->life--;
if(this->life==0){
par_sys->erase( par_sys->begin()+(oid-1) ) ;
erased=true;
};
return erased;
};


main.cpp:

int main(int argc, char** argv){
...
...
do{//Main loop
...
...
sti=0;
ishift=0;
if(psys.size()!=0){
do{
ishift=psys[sti].onstep(&psys, sti, map, mapwidth, mapheight);
sti++;
if(ishift==1){sti--;};
}while(sti };
...
...
}while(brk==false);//End of main loop
...
...
return 0;
};


Also, I can't use anything that uses the algorithm header (like the remove/erase idiom) because it gives errors for unknown reasons when I try to use remove().
Five answers:
Unca Alby
2012-08-19 16:25:19 UTC
Erasing elements from a vector can be expensive. Say, for example, you remove the second element. Every element from the third position to the end has to be moved up one position.



If you're going to be doing a lot of inserting and erasing, you probably should consider using a linked list instead. Of course, indexing into a linked list can be expensive. Depends on your application which is better.



A compromise solution is the "deque", which combines attributes of the vector and the linked list.



That being said, in any event, attempting to erase an element that no longer exists can cause a crash. There is no exception thrown, it just crashes. (One my complaints against C++, there are too many kinds of errors that *should* throw an exception that can be handled, but will crash instead.)



Also keep in mind that each time you erase elements, any iterators that existed before are invalidated. They will point to old locations that no longer exist. Attempting to use an invalidated iterator can cause a crash.



Something you can do while you're debugging, or even keep in production code, is to perform a test before performing the erase. If your test fails, throw your own exception which you can catch in some outer routine. E.g.:



if (par_sys->begin()+(oid-1)) > par_sys->size())

  throw "attempting to erase non-existent element";

else

  par_sys->erase( par_sys->begin()+(oid-1) ) ;



Anyhow, give that a try and see what happens.



EDIT: @Stephen, altho visiting stackoverflow.com is very good advice, and the ratio of experts to trolls is much better, nevertheless, just because *you* don't know the answer doesn't mean that *none* of us are able to help!
2012-08-19 16:26:58 UTC
I am not a expert, but I don't see where you pass the pointer to the next object in the vector back after the erase ?

I assume you've correctly handled the destruction (memory management) in your code but that isn't evident here.

I also don't understand why you can't just run a trace to debug your code?

Finally, how many objects do you have? moving or deleting vector objects is very inefficient and could in itself cause problems when the size of the vector is large.
cordier
2016-10-17 05:07:52 UTC
hi, (ANS) between the most ordinary motives of the Blue reveal (also ordinary because the blue reveal of lack of life) in abode windows is "device drivers" that fail to load upon abode windows initiating. And truly abode windows can not load the drivers contained in the splendid series it extremely is needed and this also ability it can not assign memory aspects easily & properly both. In different words it blows a gasket extremely. **it is termed a abode windows "quit mistakes" it extremely is a serious journey in words of the operating device. This typically ends up in abode windows dumping the contents of the operating memory right into a report on the hard disk, it is termed a "promote off report" or debug report. The motives of the crash should be analyzed via a device engineer and the motives pin pointed and the precedence solved with somewhat of luck. Ivan computing device veteran, MCSE educated.
?
2012-08-19 16:57:38 UTC
http://www.cplusplus.com/forum/general/11297/



I believe this might be your answer, but I am not really sure, because the method invoked from main is passing four parameters, where the code your provided is a method dealing with two parameters.



Beside that I was wondering, why you would be using pointers rather than references. In this context this might have unwanted side effects. ... :O)



Have fun!
Stephen
2012-08-19 16:20:13 UTC
Haha wtf? Do you actually expect almost anyone who frequents this site to know enough c to answer c++ questions? Go to www.stackoverflow.com.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...