C++掷骰子程序出现栈损坏及数组无法存储全部掷骰结果问题
问题根因
- 数组越界是所有问题的核心原因:你声明的
int countingArray[] = { 0 };仅会初始化长度为1的数组,可存储的元素只有1个。当你输入的投掷次数大于1时,循环给countingArray[rolls]赋值会直接越界写入栈内存,一方面导致存储的投掷结果丢失/异常,另一方面会覆盖栈上存储的其他变量(比如doAgain、函数返回地址等),触发栈损坏的报错。 - 冗余逻辑:
dice函数传入的total参数没有任何作用,进入函数后会直接被覆盖,完全可以删除该参数;do while的循环条件doAgain == 1 && doAgain != 0冗余,仅保留doAgain == 1即可。
修复代码
用动态大小的vector存储每次投掷结果最适配你的需求,无需提前指定长度,也不会出现越界问题,同时补充了你需要的和值统计、概率、误差率计算逻辑:
#include <iostream> #include <cstdlib> #include <ctime> #include <vector> #include <cmath> using namespace std; // 无参返回两个骰子的点数和 int dice() { int diceOne = rand() % 6 + 1; int diceTwo = rand() % 6 + 1; return diceOne + diceTwo; } int main() { srand(time(0)); int doAgain; // 索引对应点数和,值对应理论出现次数(36次投掷的理论值) double theoryCount[13] = {0,0,1,2,3,4,5,6,5,4,3,2,1}; do { int input; cout << "Please enter the number of rolls you want: "; cin >> input; // 用vector存储每次投掷的结果,自动适配大小 vector<int> countingArray; // 统计每个点数和的出现次数,索引对应和值(2-12) int stat[13] = {0}; // 执行投掷 for (int rolls = 0; rolls < input; rolls++) { int sum = dice(); countingArray.push_back(sum); stat[sum]++; } // 输出所有投掷结果 for (int i = 0; i < countingArray.size(); i++) { cout << "\ncountingArray[" << i << "]: " << countingArray[i]; } // 输出统计、概率、误差率 cout << "\n\n===== 统计结果 =====\n"; cout << "总投掷次数:" << input << "\n"; cout << "和值\t出现次数\t实际概率\t理论概率\t误差率\n"; for (int sum = 2; sum <=12; sum++) { double realProb = (double)stat[sum] / input; double theoryProb = theoryCount[sum] / 36; double error = abs(realProb - theoryProb) / theoryProb * 100; cout << sum << "\t" << stat[sum] << "\t\t" << realProb * 100 << "%\t\t" << theoryProb *100 << "%\t\t" << error << "%\n"; } // 询问是否重试 cout << "\nTry Again? (1 == yes || 0 = exit) \n"; cin >> doAgain; }while (doAgain == 1); return 0; }
说明
- 如果你一定要用数组实现,需要先获取用户输入的
input值后,动态申请数组内存:int* countingArray = new int[input];,使用完成后手动释放delete[] countingArray;,但相比vector更容易出现内存泄漏、越界问题,更推荐用vector实现。
内容的提问来源于stack exchange,提问作者user11495912
相关产品推荐
相关产品推荐

