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
相关产品推荐
相关产品推荐

