我有一个素数生成器,它可以生成unsigned int count
素数并将它们存储在全局声明的动态分配数组中numList globalPrimes
numList只是typedef unsigned int *numList
。如果 count 的值为 0,则忽略它并计算素数,直到先前计算的素数的值超过unsigned int until
除非 count 为 0,否则将忽略该值。
numList getPrimes(unsigned int count, unsigned int until)
{
unsigned int i, j;
unsigned int p = 0;
char b=1;
if(globalPrimes==NULL)
{
b=0;
globalPrimes = calloc(count>0? count:until, sizeof(int));
if(globalPrimes==NULL)
return NULL;
}
globalPrimes[0]=2; //set first 2 prime #'s in list
globalPrimes[1]=3;
for(i=2, p=5; count!=0? (i<count):(globalPrimes[i-1]<=until); p+=2) //iterate until it finds every prime number. Increments p by 2 starting from the third prime
{
if(globalPrimes[i]!=0) //if the current prime was preordained (a value was set already) skip to the next prime
{
p=globalPrimes[i++];
continue;
}
else if(globalPrimes[i]==0) //if it is 0, allocate the extra memory and find next prime
{
if(b)
globalPrimes=(numList)realloc((void *)globalPrimes, sizeof(int)*((count==0)? (until):(count+1)));
b=0;
}
for(j=0; (p%globalPrimes[j]) && globalPrimes[j]*globalPrimes[j]<p; j++); //loop through all previous primes until past half of p
if(p%globalPrimes[j]) //if the prime is still not divisible by the previous prime
globalPrimes[i++]=p; // save as the next prime
}
globalPrimes[i]=0;
globalPrimes=(numList)realloc((void *)globalPrimes, (i+(i%2)+1)*sizeof(int));
return globalPrimes;
}
在一些测试中,我发现了一个奇怪的错误。在倒数第二realloc
行,netBeans(gcc编译器)给了我一个"信号",我认为这就像运行时异常。对话框显示错误为 SIGABRT,并在未处于调试模式时中止程序。我发现此错误仅在计数为奇数时才会发生。即使我修改 realloc 的参数使其始终传递偶数,仍然存在错误。但是当我将计数修改为仅在函数开头为偶数时,它工作正常。我不知道为什么这个奇怪的细节会导致这种奇怪的行为。
行
globalPrimes[i]=0;
就在最后realloc()
损坏内存之前 - 这是刚刚超过您分配的阵列末尾的写入。
我认为您想像这样分配数组:
globalPrimes = calloc(count>0? (count + 1):until, sizeof(int));
到目前为止,我只看了使用非零count
调用函数的情况;老实说,我不确定如果使用count == 0
调用该函数并且until
是某个目标素数,可能会有什么问题。