使用Raylib开发扫雷游戏时堆上创建数组致崩溃的问题
扫雷游戏堆数组初始化导致崩溃问题分析
问题描述
使用Raylib开发扫雷游戏时,为支持自定义地图尺寸,在堆上创建bool* map和bool* overlay两个数组表示网格。保留构造函数中的数组初始化循环时程序崩溃,移除则正常运行,崩溃发生在主循环结束阶段。
相关代码
game.h
#pragma once #include <raylib.h> class Game { bool* map; bool* overlay; int width, height; public: Game(); Game(int _width, int _height, int mines, int seed, int startX, int startY); ~Game(); void tick(); void draw() const; };
Game.cpp
Game::Game(int _width, int _height, int mines, int seed, int startX, int startY) { map = new bool[width*height]; overlay = new bool[width*height]; width = _width; height = _height; for (int i = 0; i < width * height; i++) map[i] = false; for(int i = 0; i < width*height; i++) overlay[i] = true; SetRandomSeed(seed); for(int i = 0; i < mines; i++) { int x = GetRandomValue(1, width), y = GetRandomValue(1, height); while(map[(x+width*y)-1] || (x == startX && y == startY)) x = GetRandomValue(1, width), y = GetRandomValue(1, height); map[(x+width*y)-1] = true; } } void Game::draw() const { for(int y = 0; y < height; y++) for (int x = 0; x < width; x++) { if(overlay[width*y+x]) DrawRectangle(x*10,y*10, 10, 10, (y+x)%2 == 0 ? DARKGRAY : LIGHTGRAY); } }
Main.cpp
#include <raylib.h> #include "game.h" int main(void) { InitWindow(800, 450, "raylib [core] example - basic window"); Game game(24, 24, 5, 0, 0, 0); while (!WindowShouldClose()) { // 其他逻辑 game.draw(); } // 异常抛出位置 CloseWindow(); return 0; }
异常截图

问题根源
构造函数中先执行数组内存分配,再给width和height赋值,此时width*height是未初始化的垃圾值,导致分配的数组大小完全错误。后续初始化循环访问数组时,会出现内存越界,破坏堆内存结构,最终在程序结束析构对象时触发崩溃。
修复方案
调整代码顺序,先给成员变量width和height赋值,再分配数组内存:
Game::Game(int _width, int _height, int mines, int seed, int startX, int startY) { width = _width; height = _height; // 优先初始化成员变量 map = new bool[width*height]; overlay = new bool[width*height]; // 后续初始化循环及逻辑保持不变 for (int i = 0; i < width * height; i++) map[i] = false; for(int i = 0; i < width*height; i++) overlay[i] = true; SetRandomSeed(seed); for(int i = 0; i < mines; i++) { int x = GetRandomValue(1, width), y = GetRandomValue(1, height); while(map[(x+width*y)-1] || (x == startX && y == startY)) x = GetRandomValue(1, width), y = GetRandomValue(1, height); map[(x+width*y)-1] = true; } }
额外建议
- 避免使用裸指针管理堆内存,改用
std::unique_ptr<bool[]>自动释放内存,防止内存泄漏:#include <memory> class Game { std::unique_ptr<bool[]> map; std::unique_ptr<bool[]> overlay; // ... }; // 构造函数中直接初始化: map = std::make_unique<bool[]>(width*height); - 或者使用
std::vector<bool>,它会自动处理内存分配和释放,代码更简洁安全:#include <vector> class Game { std::vector<bool> map; std::vector<bool> overlay; // ... }; // 构造函数中: map.resize(width*height, false); overlay.resize(width*height, true);
内容的提问来源于stack exchange,提问作者Ignac
相关产品推荐
相关产品推荐

