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
相关产品推荐
相关产品推荐

