素因数分解程序出现Signal 11错误,定位未分配内存访问位置
素因数分解程序Signal 11错误原因及修复方案
核心问题点
- 非标准可变长度数组引发栈溢出
C++标准不支持int primes[n + 1]这种用变量定义数组长度的写法,这仅为部分编译器的扩展功能。且该类数组分配在栈空间,默认栈容量通常仅几MB,当输入的数值较大时,数组会直接超出栈容量爆栈,触发段错误。 - 整数溢出导致数组越界访问
筛法内层循环中j = i*i的计算逻辑存在溢出风险:当i的大小超过sqrt(INT_MAX)时,i*i的结果会超出int取值范围变成负数,此时j <=n的判断恒成立,循环会持续执行访问primes数组的越界地址,触发非法内存访问错误。 - 缺失边界校验
如果输入的待分解数值为0、1或者负数,数组长度n+1会小于2,后续循环从i=2开始直接访问数组不存在的下标,直接触发错误。
修复方案
- 用标准库
vector替换可变长度数组,内存分配在堆上,避免栈溢出同时符合C++标准规范 - 将筛法内层循环的j改为long long类型承接i*i的计算结果,避免整数溢出
- 增加输入边界校验,小于2的输入直接处理,不进入筛法逻辑
修正后完整代码
#include <iostream> #include <vector> using namespace std; void sieve(int n){ if(n < 2){ cout << n << " 无素因数" << endl; return; } vector<int> primes(n + 1); for(int i = 2; i <= n; i++){ primes[i] = i; } for(int i = 2; i <= n; i++){ if(primes[i] == i){ for(long long j = (long long)i * i; j <= n; j += i){ if(primes[j] == j){ primes[j] = i; } } } } while(n != 1){ cout << primes[n] << " "; n /= primes[n]; } cout << endl; } int main() { ios_base::sync_with_stdio(0); cin.tie(nullptr); int n; cin >> n; for(int i = 0; i < n; i++){ int x; cin >> x; sieve(x); } return 0; }
内容的提问来源于stack exchange,提问作者Max W
相关产品推荐
相关产品推荐

