调用vector erase删除半径小于20的元素时出现vector下标越界错误如何解决?
报错原因
- 向量不同步:你仅对存储小球位置的
ball向量执行了erase删除操作,但是存储半径的ballr、存储x/y方向速度的wx/wy三个向量完全没有同步删除对应下标的元素,导致四个向量的长度不一致,后续遍历访问下标时出现越界,同时也会出现小球位置、速度、半径对应关系错乱的问题。 - 删除循环逻辑错误:倒序遍历的
for循环本身已经在每次迭代结束时执行i--,你在else分支额外增加了一次i--,会导致每次不需要删除元素时直接跳过下一个待检查的元素,漏检半径小于20的小球,极端情况下也可能引发下标计算错误。
修复方案
首先修正删除逻辑,同步删除四个向量的对应元素,去掉多余的i--,还可额外优化碰撞检测性能,避免浮点计算误差:
// 碰撞检测逻辑(优化项:取消sqrt直接比较平方值,提升性能的同时避免浮点误差) for (int i = 0; i < ball.size() ; i++) { for (int j = i + 1; j < ball.size(); j++) { int a = ball[i].x - ball[j].x; int b = ball[i].y - ball[j].y; int rSum = ballr[i] + ballr[j]; if (a*a + b*b <= rSum*rSum) { wx[i] = -wx[i]; wx[j] = -wx[j]; wy[i] = -wy[i]; wy[j] = -wy[j]; ballr[i] *= 0.9; ballr[j] *= 0.9; } } } // 修正后的删除逻辑 for (int i = ball.size() - 1; i >= 0; i--) { if (ballr[i] < 20) { ball.erase(ball.begin() + i); ballr.erase(ballr.begin() + i); wx.erase(wx.begin() + i); wy.erase(wy.begin() + i); } }
额外优化建议:可以把小球的位置、速度、半径属性都封装到同一个Ball结构体中,仅维护一个vector<Ball>即可,从根源上避免多向量同步的问题。
内容的提问来源于stack exchange,提问作者L Ghfucn
相关产品推荐
相关产品推荐

