类中vector对象声明与push_back使用问题:运行段错误排查
错误原因
tabellone数组越界访问
类中定义的tabellone是int tabellone[9][10];,意味着行索引范围是0~8,列索引范围是0~9。但构造函数中的循环写的是:for(int j=0;j<=x_max;j++) { for (int k=0;k<=y_max;k++) { tabellone[j][k] = z; z++; } }x_max的值是9,j<=x_max会让j遍历到9,超出了tabellone的行边界(最大索引为8);同理k<=y_max会让k遍历到10,超出列边界(最大索引为9)。这种越界会破坏内存中ordervector的内部数据结构,导致后续push_back操作触发段错误。随机数生成导致
on_off数组越界estrai()中生成随机数的代码:int estrazione = int(ceil(rand()/double(RAND_MAX)*90));rand()/double(RAND_MAX)的范围是[0,1),乘以90后是[0,90),经过ceil处理后可能得到90。而on_off数组的大小是90,索引范围是0~89,访问on_off[90]会触发越界。逻辑错误:比较运算符替代赋值运算符
on_off[estrazione]==true;是比较操作,没有把对应位置设为true,属于逻辑bug,但不是段错误的直接原因。随机数种子重复初始化
每次调用estrai()都执行srand(time(NULL));,如果短时间内多次调用,time(NULL)返回的时间戳相同,会生成重复的随机数。
修复方案
1. 修复构造函数的数组循环边界
把构造函数中的循环条件修改为严格小于数组长度,同时移除多余的vector初始化(vector默认构造即为空):
Tombola::Tombola () { int z=1; for(int i=0;i<90;i++) { on_off[i] = false; } // 行范围0~8,所以j < x_max(x_max=9) for(int j=0;j<x_max;j++) { // 列范围0~9,所以k < y_max(y_max=10) for (int k=0;k<y_max;k++) { tabellone[j][k] = z; z++; } } // 随机数种子只初始化一次 srand(time(NULL)); }
2. 修复随机数生成与数组访问
修改estrai()的随机数生成逻辑,确保生成1~90的数字,同时对应on_off的正确索引:
int Tombola::estrai() { // 直接生成1~90的随机数,避免越界 int estrazione = rand() % 90 + 1; // 数字n对应on_off的索引n-1 on_off[estrazione - 1] = true; order.push_back(estrazione); return order.back(); }
3. 移除重复的随机数种子初始化
将srand(time(NULL));移到构造函数中,确保整个程序生命周期只初始化一次种子。
修复后的核心代码片段
tombola.cc构造函数与estrai()
#include "tombola.h" #include <cstdlib> #include <ctime> #include <iostream> using namespace std; Tombola::Tombola () { int z=1; for(int i=0;i<90;i++) { on_off[i] = false; } for(int j=0;j<x_max;j++) { for (int k=0;k<y_max;k++) { tabellone[j][k] = z; z++; } } srand(time(NULL)); } Tombola::~Tombola() { cout << "Tombola is destroyed" << endl; } int Tombola::estrai() { int estrazione = rand() % 90 + 1; on_off[estrazione - 1] = true; order.push_back(estrazione); return order.back(); }
内容的提问来源于stack exchange,提问作者Vittorio

