2016-04-07 15 views
-1

なぜこのプログラムでセグメンテーションフォールト(SIGSEGV)が発生しますか?要因を見つける際のセグメンテーションフォルト

私は100,200のような大きな数字の階乗を見つけようとしていますが、なぜセグメンテーションフォルトが表示されるのかわかりません。助けて。

制約:

  • 1≤T≤100000
  • 1≤N 100000
#include<stdio.h> 
int main() 
{ 
    long long int t,mod=1589540031; 
    long long int a[5000]; 
    long long int n,i,j,temp,k,x; 

    scanf("%lld",&t); 
    while(t--) 
    { 
     scanf("%lld",&n); 
     a[0]=1; 
     k=1;  

     temp = 0; 
     for(i=1;i<=n;i++) 
     { 
      for(j=0;j<k;j++) 
      { 
       x = a[j]*i+temp; 
       a[j]=x%10; 
       temp = x/10; 
      } 
      while(temp>0) 
      { 
       a[k]=temp%10; 
       temp = temp/10; 
       k++; 
      } 
     } 
     for(i=k-1;i>=0;i--) 
      printf("%lld",a[i]%mod); 
      printf("\n"); 
    } 
    return 0; 
} 
+1

segfaultを正確に入力してください。その情報は質問の一部でなければなりません。 –

+0

コードを正しくインデントできますか? – hivert

+1

元の割り当てにはリンクしませんが、_n!_ modulo _m_を計算したように見えます。その場合は、配列を使って乗算を行う必要はありません。全体を通して、[モジュラー算術](https://en.wikipedia.org/wiki/Modular_arithmetic)を使用してください。 (0から9までの数字を印刷するときは余計ですが、無意味です。) –

答えて

1

≤「a配列は5000個の要素を含めることができますが、あなたはドンt kjが5000より大きいかどうかをチェックします。

インデックスが> 5000のa配列の要素にアクセスしようとすると、未定義の動作が発生します。

for(j=0;j<k;j++) 
{ 
    x = a[j]*i+temp; // <<<<< j could be > 5000 
    a[j]=x%10; 
    temp = x/10; 
} 

while(temp>0) 
{ 
    a[k]=temp%10;  // <<<<< k could be > 5000 
    temp = temp/10; 
    k++; 
} 
... 
+1

数字100000! 5000桁をはるかに超えています - ほぼ10倍。私はあなたが各配列の桁に法を適用していることに気付きます。それはかなり間違っています。 uint64_tの範囲で製品を保つためには、乗算ごとにモジュラスを適用するはずです(これはおそらく(「挑戦」の疑問)。署名付きは使用しないでください。私はモジュラスが「1589540031」であることを見ています。これは、2乗を64ビットで保持できるため、製品は常に範囲内になければなりません。 –

+0

この問題を解決するには? –

+0

私と@MOehmはちょうどあなたに言った。しかし、私はその質問を見ていない。それがオンラインの挑戦であれば、あなた自身でそれを理解してください! –

関連する問題