我有一个函数,它应该返回一个从2到 n 的素数数组,但有时它什么也不返回,只是说“exited with code=3221225477”,特别是如果我输入了一个大于3或4的值。当它工作时,它跳过数字5并打印“2 3 29541 7 11 ..."。
有人能指出它有什么问题吗?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int *primes_in_range(int stop){
int *array_primes = malloc(sizeof(int));
int size = 1;
int 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){
array_primes = realloc(array_primes, sizeof(int)*size);
array_primes[size] = number;
size += 1;
break;
}
}
}
return array_primes;
}
int main(){
int *result = primes_in_range(8);
for (int i=0; i<8; i++) printf("%d\n", result[i]);
free(result);
return 0;
}
我在python中写了一个遵循相同算法的程序,它没有跳过任何数字,所以它一定是出于另一个原因,除非我遗漏了什么,否则它不工作。
我将在这里留下工作的python代码:
def primes_in_range(stop: int = None):
prms = [2]
for num in range(3, stop+1, 2):
aim = num**0.5
for prm in prms:
if not num % prm:
break
elif prm >= aim:
prms.append(num)
break
if stop >= 2:
return prms
else:
return []
print(primes_in_range(13))
3条答案
按热度按时间kpbwa7wx1#
你需要在调用
realloc
之前**递增size
变量,然后使用size - 1
作为新值的索引。就目前而言,你的程序正在写入一个超出分配的缓冲区范围的值(array_primes[size]
),这将导致未定义的行为(这将使程序崩溃... * 有时 *)。此外,你在列表末尾看到的“奇怪”数字也是从分配的缓冲区之外读取的值,因为你总是假设有8个值(实际上没有)。要解决这个问题,在函数中添加另一个
int*
参数,该参数可以返回找到的素数的个数,并将其用作printf
循环的终止符值:vx6bjr1n2#
这不是将元素追加到数组的方式。正确的版本可以是:
同样,您正在返回一个数组,但调用方不知道它的大小。要么返回一个包含数组及其大小的结构,要么通过地址传递一个大小以填充(输出参数),该大小也可以用作最大大小。
jogvjijk3#
正如@WeatherVane所指出的,你的mallocs/remallocs是错误的。就我个人而言,我会采取更直接的方法,使用一个单一的操作:
这在一开始就分配最坏情况的大小,有一个安全余量。realloc的效率非常低,而且在小尺寸的情况下使用它们是丑陋的。在这样的代码中所有处理realloc的额外指令()也会占用空间...所以即使简单的malloc()获取一点额外的内存,通过删除remallocs,您通常在内存游戏中仍然领先。()和支持代码。调试也更简单。
remalloc()的缺失使您可以真正简化循环。
如果由于某种原因遇到零,调用者也可能提前中断结果。经过几十年的编程,我对这种事情变得非常偏执。