-4

さて、私が作成したこの関数は、エラトステネスのふるいアルゴリズムを使用して、すべての素数 <= n を計算します。この関数は、素数と素数の数をパラメーターに格納します。

関数が終了するとき、素数は、すべての素数 <= num を保持する、動的に割り当てられたメモリのチャンクを指している必要があります。*count には素数の数が含まれます。

ここに私の関数 getPrimes があります:

void getPrimes(int usernum, int* count, int** array){
    (*count) = (usernum - 1);
    int sieve[usernum-1], primenums = 0, index, fillnum, multiple;

    //Fills the array with the numbers up to the user's ending number, usernum.
    for(index = 0, fillnum = 2; fillnum <= usernum; index++, fillnum++){
        sieve[index] = fillnum;
    }

     /*Starts crossing out non prime numbers starting with 2 because 1 is not a prime. It then deletes all of those multiples and 
     moves on to the next number that isnt crossed out, which is a prime. */
     for (; primenums < sqrt(usernum); primenums++){ //Walks through the array.
         if (sieve[primenums] != 0){ //Check's if that number is 0 which means it's crossed out
             for (multiple = (sieve[primenums]); multiple < usernum; multiple += sieve[primenums]){ //If it is not crossed out it starts deleting its multiples.
                 //Crossing multiples out and decrements count to move to next number
                 sieve[multiple + primenums] = 0;
                 --(*count);
             }
         }
     }
     int k;
     for (k = 0; k < usernum; k++)
     if (sieve[k] != 0){
         printf(" %d", sieve[k]);
     }
     printf(" ");
     array = malloc(sizeof(int) * (usernum + 1));
     assert(array);
     (*array) = sieve;
 }

ここでの関数は完全にコンパイルされますが、101 などの大きな数値を試してみると、セグメンテーション違反があることに気付きました。私のコードがセグメンテーション違反を引き起こしている場所を誰かが見ていますか?

4

1 に答える 1

1

次の 2 つのステートメントは問題です。

array = malloc(sizeof(int) * (usernum + 1));

*array = malloc...前に追加したアスタリスクに注意してくださいarray呼び出し元のポインターint**を変更するために、パラメーターを逆参照する必要があります。

(*array) = sieve;

このコードは配列をコピーせず、一時的なローカル変数のアドレスを呼び出し元のポインターに割り当てます。関数の最後で範囲外になると、sieve配列は存在しなくなります。ループを使用して、割り当てたばかりのメモリ ブロックにfor内容をコピーします。sieve

編集:

Daniel Fischer が 3 時間前に、あなたの質問の前の化身で2 番目の問題をすでに指摘しているようです。

于 2013-03-30T02:26:02.170 に答える