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

C语言素数生成函数崩溃、漏数问题排查求助

问题排查与修复

你的C代码出现崩溃、素数遗漏和乱码的问题,根源是内存越界访问和循环逻辑错误——Python列表会自动处理内存扩容,而C需要手动管理内存,这是和Python版本的核心差异。具体问题和修复如下:


1. 内存扩容错误(核心崩溃原因)

在发现新素数时,你调用realloc(array_primes, sizeof(int)*size),但此时size是当前素数数组的长度,扩容后的容量应该是size+1,否则数组空间没有增加,直接访问array_primes[size]会写入未分配的内存区域,触发内存访问错误(代码3221225477是Windows下的内存访问违例)。

修复:将realloc的大小改为sizeof(int)*(size+1)

// 错误写法
array_primes = realloc(array_primes, sizeof(int)*size);
// 正确写法
array_primes = realloc(array_primes, sizeof(int)*(size+1));

2. 素数遗漏的隐藏问题

当判断prime >= aim时,aim是sqrt(number)转成int的值,比如number=5时,sqrt(5)≈2.236,转int后aim=2,此时数组里的第一个素数是2,2 >= 2成立,会执行扩容。但如果realloc没正确扩容,写入array_primes[size](此时size=1)就会越界,可能覆盖其他内存,导致后续逻辑异常,比如遗漏5。

3. main函数循环次数错误

你在main里循环for (int i=0; i<8; i++),但返回的素数数组长度是素数的实际个数(比如输入8时只有4个素数),循环8次会访问数组末尾的未初始化内存,出现乱码值(比如29541)。

修复:需要让primes_in_range返回素数数组的长度,这里用指针参数传递长度更合理。


修正后的完整C代码

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

// 新增int* len参数,用于返回素数数组的长度
int *primes_in_range(int stop, int* len){
    if (stop < 2) {
        *len = 0;
        return NULL;
    }
    int *array_primes = malloc(sizeof(int));
    int size = 1;
    // 用double存储aim避免精度丢失
    double aim;
    int prime;

    array_primes[0] = 2;

    for (int number = 3; number <= stop; number += 2){
        aim = sqrt(number);

        for (int index = 0; index < size; index++){
            prime = array_primes[index];

            if ((number % prime) == 0){
                break;
            }
            else if (prime >= aim){
                // 扩容到size+1个元素
                array_primes = realloc(array_primes, sizeof(int)*(size+1));
                array_primes[size] = number;
                size += 1;
                break;
            }
        }
    }
    *len = size;
    return array_primes;
}

int main(){
    int len;
    int *result = primes_in_range(8, &len);
    
    // 循环次数改为实际素数个数len
    for (int i=0; i<len; i++) printf("%d\n", result[i]);
    free(result);

    return 0;
}

补充说明

  • Python的list.append()会自动处理内存扩容,不需要手动管理,所以不会出现这类问题;但C语言必须严格控制内存分配的大小,否则极易出现内存越界。
  • 用double存储aim可以避免int转换带来的精度丢失,比如sqrt(26)是5.099,转int会变成5,用double比较prime >= aim更准确。

内容的提问来源于stack exchange,提问作者M11X00

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:55:16