0

注:他のセグメンテーション違反の投稿を見てきましたが、私の問題に密接に関連しているのは、スタック上に大きな配列が作成され、最終的にオーバーフローが発生した場合です。ただし、以下のコードからわかるように、ヒープに割り当てていますが、まだこの問題が発生しています。

Valgrind と gdb の両方を使用してこれをデバッグしたところ、次のように表示されました。「サイズ 4 の無効な読み取り ... numberDivisors」または以下の関数コードでセグメンテーション違反が発生しています。奇妙なことに、これは、エラーまたはセグメンテーション違反のいずれかをスローするときに、対象の番号をループした後、49141 までのすべての番号に対して機能します。 これはループ中のみです。 ループせずに単一の大きな数を入れると、エラーやセグメンテーションなしで除数の数が返されます。以下のコードで何が問題なのか誰にもわかりますか? ありがとう!

int numberDivisors(int n) {
    int lim = (int)floor(sqrt((double)n));
    int *primes = (int*)calloc(n, sizeof(int));
    int *divisors = (int*)calloc(n, sizeof(int));
    int i, j, ctr;
    ctr = 0;

    if(primes && divisors) {
        for(i = 0; i < n; i++) {
            primes[i] = 1;
            divisors[i] = 0;
        }

        for(i = 2; i < lim; i++) {
            if(primes[i]) {
                for(j = i; i * j < n; j++) {
                    primes[i * j] = 0;
                }
            }
        }

        for(i = 2; i < n; i++) {
            if(primes[i]) {
                if(n % i == 0) divisors[i] = 1;
                for(j = i; i * j < n; j++) {
                    // int result = n % (i * j);
                    assert(i * j < n); //Added at lsk's request.  i * j passes the test.

                    //if(result == 0) {
                    if(n % (i * j) == 0) {
                        if(!divisors[i * j]) {
                            divisors[i * j] = 1;
                        }
                    }
                }
            }
        }

        for(i = 2; i < n; i++) {
            if(divisors[i]) ctr++;
        }

        ctr += 2;
    } else {
        printf("Allocation failed.");
    }
    free(primes);
    free(divisors);
    return ctr;
}

UPDATE 関数内のすべてのintをunsigned longに変更しました(機能することを確認するためだけに)、現在は正常に動作しています。ただし、Umer は正しいです。必要以上に時間がかかるため、アルゴリズムを再考する必要がありますが、それはまったく別の問題です。SOコミュニティの支援に感謝します!

4

1 に答える 1