2009-07-27 8 views
0

次のスクリプトを実行すると、セグメント化エラーが発生します。出力は「ここで5a」で構成されます。しかしそれ以上のものはありません。何が間違っているかもしれないかに関する提案はありますか?ループ内で起こっているセグメント違反の判断に役立つ必要がありますか?

if(model==1) 
    fptr3=fopen("poisson.pro","r"); 
if(model==2) 
    fptr3=fopen("jtt.pro","r"); 
if(model==3) 
    fptr3=fopen("estimate.pro","r"); 

printf ("here 5a\n"); 
for (i=0;i<20;i++) 
    fscanf(fptr3,"%lf", &freq[i]); 
printf ("here 5ai\n"); 

for (i=0;i<20;i++) 
{ 
    printf ("here 5b\n"); 
    for (j=0;j<20;j++) 
    { 
    printf ("here 5c\n"); 
    fscanf(fptr3,"%lf", &prob[i][j]); 
    if(model==3) 
     prob[i][j]=prob[i][j]/10000.0; 
    } 
} 

UPDATE

double freq[20], prob[20][20]; 
+0

あなたは実際に20を使用していますか、それとも例のためだけですか?スタックに大きな配列を割り当てることはできません。 – Ben

+0

@Ben:私は実際に20を使っています。 – shubster

答えて

2

このコードが呼び出され、「モデル」が1、2、または3のいずれかであることを確認してください。もしそうでなければ、fptr3は設定されません。それで何かをしようとすると、困ってしまうでしょう。

は、代わりにこれを試してみてください?:

void modeltest (int model) 
{ 
    FILE *fptr3 = NULL; 
    int i = 0; 
    int j = 0; 
    double freq[20], prob[20][20]; 

    if(model==1) fptr3=fopen("poisson.pro","r"); 
    if(model==2) fptr3=fopen("jtt.pro","r"); 
    if(model==3) fptr3=fopen("estimate.pro","r"); 

    printf ("here 5a\n"); 
    if (fptr3 != NULL) { 
     for (i=0;i<20;i++) fscanf(fptr3,"%lf", &freq[i]); 
     printf ("here 5ai\n"); 
     for (i=0;i<20;i++) { 
      printf ("here 5b\n"); 
      for (j=0;j<20;j++) { 
       printf ("here 5c\n"); 
       fscanf(fptr3,"%lf", &prob[i][j]); 
       if(model==3) prob[i][j]=prob[i][j]/10000.0; 
      } 
     } 
    } 
    else { 
     printf ("fptr3 is NULL!\n"); 
    } 
} 

をのadditonalノート。一貫してブレーススタイルを考慮してください! :)

0

何のFREQと定義?何がprobと定義されていますか?

最初のforループはfreqに対してfscanfを実行するだけですか?それともブロック全体を取り囲むと思われますか?

編集:理論的根拠 - あなたが見ているものがすべて5aなら、それはfreqのfscanfに違反しています。 freqのためのスペースをあまりにも割当てているかもしれませんし、誤ったタイプを使っているかもしれません。

+0

@Matthew:私はfreqとprobの定義をコードに追加しました。 – shubster

+0

編集内容に照らして、ダニエルはおそらく正しい道にあります。あなたは* fptr3が有効であることを絶対に確信していますか? –

2

これはC#ですか? segfaultsを取得している冗談はありません... 戻りコードは何ですか? ...

あなたは本当に助けのこの種のために尋ねる前に、あなたのコードを改善する必要が....これは本当に読めない、と醜いコード... スタートは、ファイルポインタ

if(1==model) 
{ 
fptr3=fopen("poisson.pro","r"); 
if(null == fptr3) 
{ 
    perror("Fopen failed"); 
} 

にいくつかのチェックを追加します

+1

それはCとタグ付けされており、コードを見ればC#ではないと思われます) –

+0

@Matthew:それはC#としてタグ付けされていましたが、明らかにCですので再タグ付けしました;) – Sean

+0

私はごめんなさい。間違って#タグを付ける必要がありました。 – shubster

2

valgrindはCのsegfaultsの主権救済策です。の前に segfaultの前にエラーがあり、間違ったことを正確に伝えます。最大限の利益を得るには、デバッグシンボルをオンにしてコンパイルしてください。

0
  1. にperrorを使用してファイルのエラーコードを必要に応じて(。ダニエルの答えを参照))(リターン・コードを確認し、印刷します。 FILE *をNULLにfscanf()を呼び出すと、必ずsegfaultが実行されます。

  2. %lfを指定した場合、freqは浮動小数点ではなく、少なくとも20倍の配列でなければなりません。 man ffrintf()を参照してください。

  3. printf()の代わりにデバッガを使用します。

+0

あなたの編集の後、ノーマンが言うようにvalgrindを使うことをお勧めします – Ben

1

私はDanielに同意します。戻り値とポインタを確認する必要があります。

また、コードをブロックして書式を設定することで、より良い仕事をする必要があることに同意します。あなたがそれを読んだ唯一の人だと仮定すると、数週間後でさえ、あなたはそれを追うことができないほど忘れ去ってしまいます。

マシューズポイントに向けて、次の行で始まるすべて削除を試みることができる:だけファイルポインタを確認した後、これを気に、もちろん

printf ("here 5ai\n"); 

を。

別の夢のようなアイデアは、デバッガを使ってそれを実行することです。私はprintfステートメントのような偉大なデバッグオプションがあるときにデバッガを使用するのは難しいことを知っていますが、時にはデバッガが巨大な時間を節約することができます。また、開発しているプラ​​ットフォームでデバッガを使用する方法を学ぶことは、平均的なハッキングパックから良いコーダを分離することの1つです。(参考、デバッガでコアを見てみることもできますし、問題のある場所を正確に見ることもできます)(ヒント:コアファイルがない場合は 'man ulimit'を試してみてください))

唯一のデバッグ手段としてprintfを使用することを主張し、各使用の直後にflushを呼び出します。

0

fscanfでクラッシュしているので、開いているファイルの先頭の内容を投稿する必要があります。ファイルが存在しないか、またはファイルを解析しようとしているときに積み重ねられたときに不正な形式になっています。

関連する問題