C++ SFML实现扫雷风格网格时出现vector下标越界错误的原因是什么?
问题根因
1. 无符号整数下溢是核心触发原因
你在toGraphCoords函数中直接将sf::Vector2i类型的鼠标坐标强制转换为uint32_t,当鼠标移动到窗口左侧、上方边界外时,鼠标坐标会出现负值:
- 负数转换为无符号整数时会发生下溢,例如
-1转uint32_t会变成4294967295这类超大数值 checkGraphBounds中写的mouseCoord.x >= 0、mouseCoord.y >= 0完全无效,无符号整数的取值范围本身就永远大于等于0- 如果你没有严格校验
inBounds为true后才访问坐标,超大的无符号索引会直接触发vector越界。
2. 可能存在坐标访问顺序错误
当前你的坐标映射逻辑为:
translatedCoords.x对应行索引,是data的第一层下标translatedCoords.y对应列索引,是data的第二层下标
正确访问格式应为graph[translatedCoords.x][translatedCoords.y],如果写反了下标顺序,在行列数不一致的网格中也会触发越界。
3. 边界校验逻辑未严格生效
除了无符号数的无效判断外,你需要确保只有inBounds为true时才访问Graph的节点,只要校验失败就直接跳过节点访问逻辑。
修复方案
- 调整坐标转换逻辑,提前处理负坐标:
sf::Vector2u toGraphCoords(sf::Vector2i mouseCoord, sf::Vector2f nodeSize) { uint32_t row = mouseCoord.y < 0 ? 0 : static_cast<uint32_t>(mouseCoord.y / nodeSize.y); uint32_t col = mouseCoord.x < 0 ? 0 : static_cast<uint32_t>(mouseCoord.x / nodeSize.x); return {row, col}; }
- 精简边界校验逻辑,删除无效判断:
bool checkGraphBounds(sf::Vector2u mouseCoord, sf::Vector2u bounds) { return mouseCoord.x < bounds.x && mouseCoord.y < bounds.y; }
- 严格限制只有校验通过后才访问节点:
sf::Vector2u translatedCoords = toGraphCoords(sf::Mouse::getPosition(window), nodeSize_); bool inBounds = checkGraphBounds(translatedCoords, graph.dimension()); if (inBounds) { // 仅校验通过后才执行节点访问逻辑 Node& node = graph[translatedCoords.x][translatedCoords.y]; // 后续业务逻辑 }
内容的提问来源于stack exchange,提问作者a a
相关产品推荐
相关产品推荐

