C++游戏网格碰撞检测:向vector添加坦克指针时程序崩溃
坦克碰撞网格系统崩溃问题排查
问题概述
我正在为游戏实现一个用于检测坦克碰撞的网格系统,目标是设置约40个单元格,每个单元格包含存储坦克指针的vector。坦克移动时需更新至对应单元格,但首次向vector添加坦克指针时程序崩溃,抛出异常:Exception thrown: Access violation reading。
相关代码
主逻辑代码
vec2 position{ start_blue_x + ((i % max_rows) * spacing), start_blue_y + ((i / max_rows) * spacing) }; Cell* tank_cell = Cell::find_cell_for_tank(position.x, position.y, cells); Tank tank = Tank(position.x, position.y, BLUE, tank_cell, &tank_blue, &smoke, 1100.f, position.y + 16, tank_radius, tank_max_health, tank_max_speed); tank_cell->tanks.push_back(&tank);
cell.h 构造函数声明
Cell(int column, int row, vector<Tank*> tanks);
Cell::find_cell_for_tank() 实现
Cell* Cell::find_cell_for_tank(int pos_x, int pos_y, vector<Cell*>& cells) { int tank_col = pos_x / CELL_WIDTH; int tank_row = pos_y / CELL_HEIGHT; for (int i = 0; i < cells.size(); i++) { if ((*cells.at(i)).column == tank_col && (*cells.at(i)).row == tank_row) { return cells.at(i); } } Cell* new_cell = &Cell(tank_col, tank_row, {}); cells.push_back(new_cell); return new_cell; }
崩溃原因分析
临时Cell对象导致野指针:在
find_cell_for_tank函数中,&Cell(tank_col, tank_row, {})取的是临时Cell对象的地址。临时对象会在该行代码执行结束后立即被销毁,返回的new_cell变成野指针。后续访问tank_cell->tanks时,实际是访问已释放的内存,触发访问违规。栈上Tank对象指针悬空:主逻辑中的
Tank tank是栈上的局部对象,当当前代码块执行完毕后,该对象会被销毁,存入单元格vector的指针也会变成无效指针,后续操作必然出错。
修复方案
1. 正确创建Cell对象
改用动态分配创建Cell,确保内存不会被自动释放:
Cell* new_cell = new Cell(tank_col, tank_row, {}); cells.push_back(new_cell); return new_cell;
注意:游戏结束或不再需要这些Cell时,要遍历
cells用delete逐个清理,避免内存泄漏。
2. 正确存储Tank指针
不要存储栈上Tank的指针,改用动态分配创建Tank:
Tank* tank = new Tank(position.x, position.y, BLUE, tank_cell, &tank_blue, &smoke, 1100.f, position.y + 16, tank_radius, tank_max_health, tank_max_speed); tank_cell->tanks.push_back(tank);
注意:坦克被销毁(比如被击毁)或游戏结束时,要从单元格的
vector中移除并delete对应的Tank对象,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Bas van der Veen
相关产品推荐
相关产品推荐

