我有一个素数生成器,它生成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,并且它在不处于调试模式时中止程序。我发现只有当count为奇数时才会出现此错误。即使我修改realloc的参数以便它总是传递偶数,但仍然存在错误。但是当我将count修改为仅在函数的开头时,它工作正常。我无法弄清楚为什么这些奇怪的细节会导致这种奇怪的行为。
答案 0 :(得分:1)
该行
globalPrimes[i]=0;
就在您的上一个realloc()
破坏内存之前 - 这是一个刚刚超出您已分配的数组末尾的写入。
我想你想像这样分配数组:
globalPrimes = calloc(count>0? (count + 1):until, sizeof(int));
到目前为止,我只研究了使用非零count
调用函数的情况;老实说,如果用count == 0
和until
作为目标素数来调用函数,我可能不确定会出现什么问题。