2017-07-04 165 views
-4

我只有幾天進入C編程。我想重寫一個計算C語言中的素數的小程序,看看它比Java(我來自的編程語言)運行速度快多少。C程序有時會崩潰,有時候不會崩潰

我現在遇到了一個(對我)很奇怪的問題。有時程序工作正常,編譯和終止,但有時它崩潰在「calculateNewPrimes()」函數的某處。 Eclipse不顯示任何錯誤消息,編譯看起來也能正常工作。有沒有人看到這個錯誤,並可以爲我這樣的c-newbie指出來? :)在此網站和其他網頁上的以前的研究沒有帶來任何結果。

全局變量:

#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); 
    } 
+0

它會崩潰嗎?還是掛起?標題似乎與身體相矛盾。 – Carcigenicate

+0

你做了什麼調試?它在哪裏被卡住**完全** /它崩潰的錯誤是什麼? – Carcigenicate

+0

隨機崩潰通常來自訪問單元化/釋放內存 – Dunno

回答

1

好的,從這裏開始有幾個指針。

你說,「它似乎卡住」,有時。讓我們分析一下:

  1. 你的意思是程序掛起了?你怎麼知道它在這個 函數中?你打入調試器了嗎?
  2. 「有時」與輸入有任何關係嗎?或者它是隨機的? 「輸入」將包括您輸入的文件和數字。
  3. 該程序是否曾經崩潰?

建議#1:如果程序掛起,你應該能夠闖入它在調試器中,然後通過單步執行代碼,看看它是怎麼了。否則,關鍵位置的一些打印語句可以給你提供調試提示。

現在代碼本身。

  1. 你必須在代碼中出現明顯錯誤,如中提到 - GAURANG VYAS's comment 。在函數退出後,您通過全局指針 (temp)引用局部變量。這可能導致 導致不一致的行爲,崩潰等。
  2. 你有一個else if有一些複雜的條件。如果你不是C運營商優先的專家,你可能會或可能不會按照你自己的想法去做。 (即使你說得對,下一個閱讀代碼的人可能不會!)。我建議使用括號。
  3. 好的,我複製,編譯並運行您的代碼。你將進入一個無限循環,它似乎與你輸入的數字有關。5似乎總是工作,6沒有。這是一個有用的線索;當數字變大時,退出循環的條件將失敗。同樣,由於您正在引用已釋放的內存,因此您可能在此使用無效數據。

嘗試添加行 -
current+=2;
,你會看到你在無限循環立即printf("current is %d\n", current);;它只是不斷增加。

這是足夠的信息讓您繼續調試。

+0

或許。考慮到這個問題的形式,我認爲這是一個合理的答案。你可以自由地不同意:-)並且可能是對的...... – Basya

+0

謝謝Gaurang Vyas的編輯。我看到我有很多東西要學習如何在這裏編寫和格式化答案! – Basya