C程序有时会崩溃,有时则不会崩溃

时间:2017-07-04 12:39:38

标签: c

我进入C编程只有几天。我想重写一个用于计算C中素数的小程序,看看它与Java(我来自的编程语言)的运行速度有多快。

我现在遇到了一个(对我而言)非常奇怪的问题。有时程序工作正常,编译和终止,但有时它会在" calculateNewPrimes()"中的某个地方崩溃。功能。 Eclipse没有显示任何错误消息,编译似乎也可以正常工作。有没有人看到这个错误,可以指出一个像我这样的新手呢? :)以前对本网站和其他网页的研究没有带来任何结果。

全局变量:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

void prepareSession();
void calculateNewPrimes();
void saveResults();

// you can modify the filepath here if you're on a new machine
char filePath[] = "/home/userName/Eclipse/workspace/PrimeNumbers/primes.txt";

// the available system memory or the maxAmount of memory you would like
// to use for the storage of the prime-numbers in BYTES
long long int memorySize = 7000000000LL;

//The file where the prime numbers will be saved
FILE *file;

// We begin with the number 3, so that we only have to check odd numbers.
// 2 is therefore already discovered (amount = 1)
long long int oldAmount = 1;
long long int current = 3;

// a pointer to the array with the already known primes
long long int *knownPrimes;
long long int *newPrimes;

该计划包括3个功能。第一个从内存中的先前计算中读取素数,第二个计算新素数,最后一个函数将新计算的素数保存回文件。

int main(){
    prepareSession();
    calculateNewPrimes();
    saveResults();
}

函数prepareSession()似乎工作正常。您可以假设该文件尚未存在且使用了启动条件。​​

void prepareSession(){
    // try to open the file, if the file doesn't exist it will be created
    file = fopen(filePath,"a+");
    long long int temp = -1;
    fscanf(file,"%lli",&temp);
    // if the file isn't empty, read the amount and the highest number in their variables
    if(temp != -1){
        /*some code */
    }
    else{
        // the file was newly created so the only known prime is 2
        printf("File doesn't yet exist. \n");
        long long int temp[1] = {2};
        knownPrimes = temp;
    }
    fclose (file);
}

关键功能。在这里的某处发生错误。

void calculateNewPrimes(){
        long long int newAmount;
        long long int primesFound = 0;

        printf("How many new primes would you like to calculate? \n");
        scanf("%lli",&newAmount);
        printf("I will calculate %lli new primes. \n",newAmount);
        long long int temp[newAmount];
        newPrimes = temp;

        //prepare measuring
        double progress=0.0;
        int oldProgress=0;
        time_t start = time(0);

        long long int currentNumber,oldNumber;
        // start the calculations
        while(primesFound < newAmount){
            oldNumber = 2;
            for(long long int i = 1; i < oldAmount + newAmount; i++){
                if(i < oldAmount){currentNumber = *(knownPrimes + i);}
                else{ currentNumber = *(newPrimes + (i-oldAmount));}

                if(current % currentNumber == 0){
                    break;
                }
                else if(currentNumber > current/oldNumber || i == oldAmount + primesFound-1){
                    *(newPrimes + primesFound++) = current;
                    printf("Found Nr.%lli: %lli \n",primesFound,current);
                    progress = (primesFound)/(double) newAmount;
                    while(oldProgress/100.0 < progress){
                            printf("%d \n",++oldProgress);
                    }
                    break;
                }
            }
            current+=2;
        }
        double timeDifference = difftime( time(0), start);
        printf("It took %g to calculate %lli new Primes \n",timeDifference, newAmount);
    }

1 个答案:

答案 0 :(得分:1)

好的,这里有一些指示。

你说,“它似乎陷入困境”,有时候。让我们打破这个:

  1. 你的意思是程序挂起?你怎么知道它在这里 功能?你有没有进入调试器?
  2. “有时”是否与输入有任何关系?还是随机的? “输入”将包括文件和您输入的数字。
  3. 程序是否会崩溃?
  4. 建议#1:如果程序挂起,您应该能够在调试器中进入它,然后逐步执行代码以查看它出错的地方。否则,关键位置的一些打印语句可以为您提供调试提示。

    现在代码本身。

    1. 您在代码中有明显的错误,如GAURANG VYAS's comment中所述 。您正通过全局引用局部变量 函数退出后的指针(temp)。仅这一点就可以 导致行为不一致,崩溃等等。
    2. 你的else if条件有些复杂。如果您不是C运算符优先级的高手,您可能会或可能不会按照您的想法行事。 (即使你说得对,下一个阅读代码的人也可能不会!)。我建议使用括号。
    3. 好的,我复制,编译并运行了你的代码。您将进入无限循环,它似乎与您输入的数字有关。 5似乎总是有效,6没有。这是一个有用的线索;当数字变大时,退出循环的条件会失败。同样,由于您正在引用释放的内存,因此您可能在此处使用了无效数据。
    4. 尝试添加该行 -
      printf("current is %d\n", current);之后立即current+=2; 你会看到你处于一个无限循环中;它只是不断增加。

      希望您有足够的信息继续调试。