奇怪的realloc行为奇怪/甚至netbeans

时间:2012-12-05 00:50:25

标签: c netbeans realloc

我有一个素数生成器,它生成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修改为仅在函数的开头时,它工作正常。我无法弄清楚为什么这些奇怪的细节会导致这种奇怪的行为。

1 个答案:

答案 0 :(得分:1)

该行

globalPrimes[i]=0;

就在您的上一个realloc()破坏内存之前 - 这是一个刚刚超出您已分配的数组末尾的写入。

我想你想像这样分配数组:

globalPrimes = calloc(count>0? (count + 1):until, sizeof(int));

到目前为止,我只研究了使用非零count调用函数的情况;老实说,如果用count == 0until作为目标素数来调用函数,我可能不确定会出现什么问题。