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

计算质数的C程序在maxCheck超过50万时触发段错误

计算质数的C程序在maxCheck超过50万时触发段错误

你的问题根源非常明确:栈溢出(Stack Overflow),和整数溢出完全无关——50万远小于INT_MAX(2147483647),完全不用担心超出int的取值范围。

为什么会出现段错误?

你在main函数里声明的previousPrimes是栈上的局部数组:

int previousPrimes[maxCheck];

栈是操作系统为每个线程分配的小块内存,通常只有几MB到十几MB(比如Linux默认栈大小一般为8MB)。当maxCheck达到50万时,这个数组的大小是500000 * sizeof(int),也就是2000000字节(约2MB),看起来还在栈的范围内,但如果maxCheck继续增大(比如100万就是4MB),再加上栈上其他变量、函数调用栈帧的开销,很快就会耗尽栈空间,触发段错误,或者因为栈被破坏导致程序执行流程混乱,出现无响应的情况。

而堆(Heap)的内存空间几乎等同于系统的可用内存,静态存储区的空间也远大于栈,这两个区域才适合存放大型数组。

解决方案

方案1:动态内存分配(推荐)

在堆上用malloc分配数组,用完记得用free释放内存,这是最灵活的方案,能支持极大的maxCheck:

int main(int argc,char *argv[]) {
    int i;
    // 动态分配堆内存,检查分配是否成功
    int *previousPrimes = malloc(maxCheck * sizeof(int));
    if (previousPrimes == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }

    currentNumPrimes = 0; // 确保计数变量初始化(如果之前未做)

    for (int i = 2; i < (maxCheck + 1); i++) {
        if (checkForPrime(i, previousPrimes)) {
            previousPrimes[currentNumPrimes] = i;
            currentNumPrimes++;
            printf("%s%d Is Prime\n", green, i);
        } else {
            printf("%s%d Is Not Prime\n", cyan, i);
        }            
    }
    printf("\n%s%f percent of numbers checked were prime", normal, ((double)currentNumPrimes / (double)maxCheck * 100));

    // 释放堆内存,避免内存泄漏
    free(previousPrimes);
    return 0;
}

方案2:将数组声明为静态

静态数组会被分配到静态存储区(而非栈上),静态存储区的空间远大于栈:

int main(int argc,char *argv[]) {
    int i;
    static int previousPrimes[maxCheck]; // 加static关键字

    // 后续逻辑与原代码一致...
}

不过静态变量的生命周期是整个程序运行期间,若maxCheck是极端大的数值,静态存储区也可能不够用,因此动态分配仍是更优选择。

其他小建议

  1. 优化全局变量的使用:你的currentNumPrimes看起来是全局变量,虽然能正常工作,但建议改成通过参数传递给checkForPrime函数,让代码更模块化、可维护:

    int checkForPrime(int num, int previousPrimes[], int currentNumPrimes) {
        int i;
        for (i = 0; i < currentNumPrimes; i++) {
            if (num % previousPrimes[i] == 0) {
                return 0;
            }
        }
        return 1;
    }
    

    调用时修改为:if (checkForPrime(i, previousPrimes, currentNumPrimes))

  2. 关于数组初始化:你提到没有初始化数组,这在你的逻辑里是完全没问题的——只有currentNumPrimes之前的元素会被赋值和访问,后续未初始化的元素不会被用到,因此初始化与否不影响功能。

总结

你的质数判断逻辑是完全可行的,问题仅出在大型数组的存储位置上:栈空间太小,无法容纳几十万元素的数组。换成堆分配或静态数组就能彻底解决这个问题,让程序支持更大的maxCheck。

备注:内容来源于stack exchange,提问作者Gbotdays

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 09:44:36