2017-07-04 16 views
-4

Cのプログラミングに数日しかかかりません。私はC言語の素数を計算するための小さなプログラムを書き直して、Java(私が出てくるプログラミング言語)に比べて実行速度がどれほど速いのか見たいと思っていました。Cプログラムがクラッシュすることがあり、時にはエラーになることはありません。

私は(私に)非常に奇妙な問題が発生しました。ときどきプログラムはうまく動作し、コンパイルして終了することがありますが、 "calculateNewPrimes()"関数のどこかでクラッシュすることがあります。 Eclipseはエラーメッセージを表示せず、コンパイルも正常に動作しているようです。誰かが間違いを見て、私のようなc-newbieのためにそれを指摘できますか? :)このサイトや他のWebページに関する以前の研究は結果をもたらしませんでした。

グローバル変数:

#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つの機能で構成されています。最初のものはメモリ内の以前の計算からの素数を読み込み、2番目の素数は新しい素数を計算し、最後の関数は新しく計算された素数をファイルに保存し直します。

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

[OK]をここから始めてください。

あなたは「たどり着く」と言います。これを解読しましょう:

  1. プログラムがハングアップしているのですか?この の機能にはどのようになっているのですか?デバッガに慣れましたか?
  2. "時には"入力と関係がありますか?それともランダムですか? 「入力」には、ファイルと入力した番号の両方が含まれます。
  3. プログラムがクラッシュすることはありますか?

投書#1:は、プログラムがハングした場合は、デバッガでそれに侵入し、それが間違って起こっている場所を確認するために、コードをステップ実行することができるはずです。そうしないと、主要な場所にあるいくつかのprint文がデバッグヒントを与えることがあります。

これでコード自体が完成しました。

  1. で述べたようにあなたは、コード内で明確なバグを持っている - GAURANG VYAS's comment 。関数が終了した後で、グローバル変数 ポインタ(temp)を介してローカル変数を参照しています。これだけでも は動作が一貫しない、クラッシュするなどの可能性があります。
  2. 多少複雑な状態のelse ifがあります。あなたがCの演算子の優先順位の騒動ではない場合、あなたはあなたが思っていることを行っているかもしれないし、していないかもしれません。 (たとえ正しいことがあっても、コードを読んでいる次の人はそうでないかもしれません!)。私はカッコを使用することをお勧めします。
  3. OK、コードをコピー、コンパイル、実行しました。あなたは無限ループに入り、それは入力した数字に関連しているようです。5はいつも動作しているようですが、6はありません。これは便利な手掛かりです。番号が大きくなると、ループを終了する条件が失敗します。ここでも、解放されたメモリを参照しているため、ここでは無効なデータを使用している可能性があります。

てみ行追加する - すぐcurrent+=2;

printf("current is %d\n", current);を、あなたが無限ループしていることがわかります。それだけで増加し続けます。

これは、デバッグを続行するのに十分な情報です。

+0

。しかし、質問の形を考えると、これは合理的な答えだと思いました。あなたは意見を異にすることが自由です:-)そして、正しいかもしれません... – Basya

+0

編集のためのGaurang Vyasありがとうございました。私はここに答えを書いて書式を設定する方法を学ぶことがたくさんあることがわかります! – Basya

関連する問題