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

C++二维数组随机填充出现Segmentation Fault问题求助

问题:二维数组随机填充时触发Segmentation Fault错误

运行时需根据传入的二维数组维度与5种元素的占比百分比随机填充数组,但终端抛出Segmentation Fault,调试时错误信息如下:

EXC_BAD_ACCESS (code=2, address=0x16f603fe8)

代码文件

Level.h

#ifndef LEVEL_H
#define LEVEL_H

#include <cmath>
#include <iostream>
#include <time.h>
#include <stdio.h>
#include "Mario.h"


using namespace std;

//Class for level
class Level{
public:
    //Constructor for level, which takes in the array dimensions
    //Also takes in the percentages chosen by the file, for how many coins, nothing spaces, goomba and koopa's
    //are present in the array (world)
    Level(int dimension, int coinPrct, int nothingPrct, int goombaPcrt, int koopaPrct, int mushPcrt);
    
    //Default destructor
    ~Level();

    void populate();

    char nextItem();
    
//Private member variables
private:
    char *m_levelAry;
    int m_coins;
    int m_nothing;
    int m_goombas;
    int m_koopas;
    int m_mushrooms;
    int m_dimension;
};

#endif

Level.cpp

#include "Level.h"

//Constructor handles dimensions of the array and odds of how frequent coins, enemies and nothing spawn
Level::Level(int dimension, int coinPrct, int nothingPrct, int goombaPcrt, int koopaPrct, int mushPcrt){
    m_dimension = dimension;
    m_levelAry = new char [dimension * dimension];
    m_coins = round((coinPrct/100.0) * (dimension * dimension));
    m_nothing = round((nothingPrct/100.0) * (dimension * dimension));
    m_goombas = round((goombaPcrt/100.0) * (dimension * dimension));
    m_koopas = round((koopaPrct/100.0) * (dimension * dimension));
    m_mushrooms = round((mushPcrt/100.0) * (dimension * dimension));

    /*
    srand(time(NULL));
    
    for (int i = 0; i < dimension; i++){
        for (int j = 0; j < dimension; j++){
            m_levelAry[i * dimension + j] = nextItem();
        }
    }

    for (int i = 0; i < dimension; i++){
        for (int j = 0; j < dimension; i++){
            cout << m_levelAry[i * dimension + j] << " ";
        }
        cout << endl;
    }
    */
}

Level::~Level(){
    delete[] m_levelAry;
}

void Level::populate(){
    srand(time(NULL));
    
    for (int i = 0; i < m_dimension; i++){
        for (int j = 0; j < m_dimension; j++){
            m_levelAry[i * m_dimension + j] = nextItem();
        }
    }

    for (int i = 0; i < m_dimension; i++){
        for (int j = 0; j < m_dimension; i++){
            cout << m_levelAry[i * m_dimension + j] << " ";
        }
        cout << endl;
    }
}


char Level::nextItem(){
    int randItemNum = (rand() % 4) + 1;
    switch (randItemNum){
        case 1:
            if (m_coins != 0){
                m_coins -= 1;
                return 'c';
            } else {
                return nextItem();
            }
            break;
        case 2:
            if (m_nothing != 0){
                m_nothing -= 1;
                return 'x';
            } else {
                return nextItem();
            }
            break;
        case 3:
            if (m_goombas != 0){
                m_goombas -= 1;
                return 'g';
            } else {
                return nextItem();
            }
            break;
        case 4:
            if (m_koopas != 0){
                m_koopas -= 1;
                return 'k';
            } else {
                return nextItem();
            }
            break;
        case 5:
            if (m_mushrooms != 0){
                m_mushrooms -= 1;
                return 'm';
            } else {
                return nextItem();
            }
            break;
        default:
            return NULL;
            break;
    }
}

int main(int argc, char const *argv[])
{
    Level level1(5, 25, 47, 8, 8, 12);
    level1.populate();
    return 0;
}

错误原因及修复方案

1. 输出循环的致命边界错误

populate()方法的输出内层循环中,增量变量写错:

for (int j = 0; j < m_dimension; i++){

此处应使用j++而非i++,错误写法会导致i持续递增超出数组边界,访问非法内存直接触发Segmentation Fault。
修复后:

for (int j = 0; j < m_dimension; j++){

2. 随机数范围错误

nextItem()中生成随机数的代码:

int randItemNum = (rand() % 4) + 1;

rand()%4生成0-3的数值,加1后范围是1-4,永远无法触发case5的蘑菇逻辑。当其他元素计数耗尽时,会无限递归调用nextItem(),最终导致栈溢出触发Segmentation Fault。
修复随机数范围:

int randItemNum = (rand() % 5) + 1; // 生成1-5的随机数

3. 递归终止逻辑缺失

当所有元素计数都为0时,nextItem()会无限递归。需添加兜底逻辑避免栈溢出:

default:
    return 'x'; // 返回默认空元素
    break;

4. 随机数种子重复初始化问题

populate()中每次调用都执行srand(time(NULL)),短时间内多次调用会导致随机数重复。应将随机数种子初始化放在程序启动阶段(如main函数开头):

int main(int argc, char const *argv[])
{
    srand(time(NULL)); // 仅初始化一次随机数种子
    Level level1(5, 25, 47, 8, 8, 12);
    level1.populate();
    return 0;
}

同时删除populate()内的srand(time(NULL))语句。

5. 百分比计数校验(可选)

若传入的百分比总和不为100,计算出的元素总数会与数组大小不一致,可在构造函数中添加校验逻辑,确保计数总和等于dimension*dimension。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:25:32