昨天我遇到问题,程序崩溃。第一个提示容器迭代器不可引用,第二个提示库超出范围
绿色史莱姆在释放蓝色史莱姆后崩溃。从调用堆栈里面发现是精灵管理器的update函数里,调用精灵的update函数更新后就崩溃了。之后在更新前后打印精灵的名字,一开始怀疑是释放的蓝色史莱姆问题,结果发现是绿色史莱姆更新后崩溃
void update(){
...
for (auto sprite = vec.begin();sprite != vec.end();){
(*sprite)->update();
//在这里崩溃
if((*sprite)->is_sprite_alive()){
sprite++;
}else{
//删除精灵
//...
sprite = vec.erase(sprite);
}
}
}在断点发现精灵迭代器指向的位置已经不可用了。我怀疑是不是销毁了什么东西。我就定位到精灵类的update函数,在绿色史莱姆更新时打印一些信息。确认在哪里开始崩溃的。结果发现整个绿色史莱姆的update函数运行完了也没有崩溃。而跳出这个函数回到了精灵管理器,再使用这个精灵就会崩溃。
所以我就陷入疑惑。在函数执行时没有问题和崩溃,之后就崩溃了。
后来我就关闭了电脑看了一会周淑怡的直播,准备睡觉。之后想出了原因,迭代器失效。在绿色精灵的update函数里会更新技能,而技能会创建蓝色史莱姆,创建后导致精灵容器内容增加,迭代器失效。
第二天尝试这个原因,把迭代器遍历改成索引遍历,果然就不崩溃了。
for(unsigned int i=0; i<vec.size(); ){
vec.at(i)->update();
if(vec.at(i)->is_sprite_alive()){
i++;
}else{
//销毁精灵
...
vec.erase(vec.begin()+i);
}
}问AI说删除元素会让迭代器失效,增加元素不会元素改变顺序,不会导致迭代器失效。但是不知道为什么我这里确实失效了。我也不想知道了。反正已经解决了。
总结
一般程序崩溃无非就是使用了使用了空指针,没有实例化指针,指针地址被改变和不可用,操作销毁后的实例,总之就是指针,迭代器,访问越界的问题。是设计的缺陷。