You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Conway生命游戏非对称数组索引越界问题求助

康威生命游戏非对称数组崩溃问题排查与修复

核心问题现象

开发C++版康威生命游戏时遇到以下异常:

  • Qt GUI中使用非对称数组(行≠列)时,程序因索引越界直接崩溃;后端Board类设15×15时,GUI增加列数无异常,但行数超过15就崩溃,行数小于15则正常。
  • 命令行测试:行数大于列数时,check_index函数会提示索引错误但程序仍能运行;行数小于列数时,编译通过但无任何输出。

代码中的关键错误

1. 索引维度完全颠倒(最致命问题)

Board类中,m_gameboard的分配逻辑是:外层数组长度对应宽度(列数m_width),每个内层数组长度对应高度(行数m_height),即m_gameboard[x][y]中:

  • x是列索引(范围0~m_width-1)
  • y是行索引(范围0~m_height-1)

但GameController::NextGeneration的循环逻辑完全颠倒,把行索引当成列索引使用,直接触发越界:

// 错误:i是行索引(对应y),却用来访问外层数组(应使用列索引)
for (int i = 0; i < m_GameBoard.GetHeight(); i++)
{
    for (int j = 0; j < m_GameBoard.GetWidth(); j++)
    {
        // 错误:active_states_detector[i][j] 用行索引访问外层数组
        if (active_states_detector[i][j] == true)
        {
            // 错误:把行i、列j传给check_neighborhood的x、y,参数顺序完全颠倒
            if (m_GameBoard.check_neighborhood(i, j) != 3 and m_GameBoard.check_neighborhood(i, j) != 2)
                m_GameBoard.temp_remove_cell(i, j);
        }
    }
}

2. check_neighborhood函数缺少默认返回值

当check_index(x,y)为false时,函数无返回语句,会返回随机值,导致后续逻辑混乱:

int Board::check_neighborhood(int x, int y)
{
    if (check_index(x, y) == true)
    {
        // 正常计数逻辑
        return counter_of_true_states;
    }
    // 无返回值,触发未定义行为
}

3. 细胞存活判断条件写法不规范

(j or i) != 0虽然逻辑等价于i != 0 || j != 0,但or作为C++逻辑或关键字可读性极差,容易和位运算混淆。

4. 内存释放函数拼写错误

deallocate_temp_gameboad应为deallocate_temp_gameboard,拼写错误会导致临时数组无法正确释放,引发内存泄漏。

修复方案

1. 修正索引维度对应关系

所有函数调用严格遵循x=列索引,y=行索引的规则,修复GameController::NextGeneration:

void GameController::NextGeneration()
{
    m_GameBoard.copy_GameBoard_to_Temp();
    bool** active_states_detector = m_GameBoard.GetGameBoard();
    // 明确区分行(y)和列(x)的循环顺序
    for (int y = 0; y < m_GameBoard.GetHeight(); y++)
    {
        for (int x = 0; x < m_GameBoard.GetWidth(); x++)
        {
            if (active_states_detector[x][y] == true)
            {
                if (m_GameBoard.check_neighborhood(x, y) != 3 && m_GameBoard.check_neighborhood(x, y) != 2)
                    m_GameBoard.temp_remove_cell(x, y);
            }
            else if (active_states_detector[x][y] == false)
            {
                if (m_GameBoard.check_neighborhood(x, y) == 3)
                    m_GameBoard.temp_add_cell(x, y);
            }
        }
    }
    m_GameBoard.print_temp_gameboard();
    m_GameBoard.reset_array('G');
    m_GameBoard.copy_Temp_to_Gameboard();
    m_GameBoard.reset_array('T');
    std::cout << std::endl << "=====================" << std::endl << std::endl;
}

2. 给check_neighborhood添加默认返回值

索引无效时返回0(符合生命游戏边界细胞规则):

int Board::check_neighborhood(int x, int y)
{
    if (check_index(x, y) == true)
    {
        int counter_of_true_states = 0;
        for (int i = -1; i < 2; i++)
        {
            for (int j = -1; j < 2; j++)
            {
                if (check_index(x + i, y + j) == true)
                {
                    // 修正条件写法,增强可读性
                    if (m_gameboard[x + i][y + j] == true && (i != 0 || j != 0))
                        counter_of_true_states++;
                }
            }
        }
        return counter_of_true_states;
    }
    // 索引无效时返回0
    return 0;
}

3. 修正内存释放函数拼写

void deallocate_temp_gameboard() // 修正拼写错误
{
    if (m_temp_gameboard != nullptr)
    {
        for (int i = 0; i < m_width; i++)
            delete[] m_temp_gameboard[i];

        delete[] m_temp_gameboard;
    }
}

4. (可选)用安全容器替代原生指针

建议用std::vector<std::vector<bool>>替代bool**,避免手动内存管理漏洞:

// Board.h中替换成员变量
std::vector<std::vector<bool>> m_gameboard;
std::vector<std::vector<bool>> m_temp_gameboard;

// 分配数组函数简化为
void allocate_gameboard(int width, int height)
{
    m_gameboard.assign(width, std::vector<bool>(height, false));
}

修复效果验证

修复后:

  • 非对称数组(行≠列)可正常运行,无索引越界崩溃。
  • 命令行测试所有行列组合均能正确输出,check_index仅在传入无效索引时触发错误提示。

内容的提问来源于stack exchange,提问作者Jano532

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:44:54