2011-01-22 13 views
0

私はそれが私がそれを望む方法の数字のリストを生成するプログラム(誰のコードが下に利用可能です)を持っています。プログラムは正常に動作し、正確に私がしたいものです。私はそれを書いた方法のファンではない。私が1つのことを変更すると、「セグメンテーションフォールト」が返されます。ここでは、コードです:今(別の)Cループとデータ構造に関する質問

#include "stdio.h" 
#include "stdlib.h" 
#define NCH 81 

// Generate swap-mode data for bonds for input.conf file 

int main() 
{ 
    int i,j,k; 
    int **dat2, *dat; 
    //double *dat; 

    int ns = 500; 

    int nrow = NCH*(ns-1); 

    dat = (int*) calloc(nrow, sizeof(int)); 
    dat2 = (int**) calloc(nrow,sizeof(int*)); 

    for (i=0; i<nrow; i++) { 
     dat2[i] = (int*) calloc(2, sizeof(int)); 
     for (j=0; j<2; j++) 
      dat2[i][j] = 0; 
    } 

    // Generates the bonds 
    k=2; 
    for (i=0; i<nrow; i++) { 
     k--; 
     for (j=0; j<2; j++) { 
      dat2[i][j] = k++; 
      if (((k%501) == 0)) { 
       k--; 
       dat2[i][j] = k++; 
       k++; 
      } 
     } 
    } 

    FILE *inp2; 
    inp2 = fopen("bonds.out", "w"); 

    for (i=1; i<=nrow; i++) 
     fprintf(inp2, "%d %d\n", dat2[i-1][0], dat2[i-1][1]); 

    fclose(inp2); 

    // Generates the bond ID in the pattern 1 2 3 3 2 1 ... (appropriate for Bond swap!) 
    k=1; 
    while (k < nrow) { 
     for (j=0; j<250; j++) { 
      dat[k] = (j+1); 
      k++; 
     } 
     for (j=250; j>0; j--) { 
      dat[k] = j; 
      k++; 
     } 
    } 

    // Scans bonds.out (because just reporting dat2[][] returns segmentation error, not sure why. 
    // scans the bonds.out file and stores both values into dm1 and dm2, then reports into 'results.out' file 
    int dm1, dm2; 

    FILE *inp; 
    inp = fopen("input.out", "w"); 
    inp2 = fopen("bonds.out", "r"); 

    for (i=1; i<=nrow; i++) { 
     fscanf(inp2, "%d %d", &dm1, &dm2); 
     fprintf(inp, "%d %d %d %d\n", i, dat[i], dm1, dm2); 
    } 



    printf("\nDone. All data has been written to \"input.out\"\n"); 

    fclose(inp2); 
    fclose(inp); 

    return 0; 
} 

は、私はそれが最初のファイルへのdat2[][]を書き込み、その後、値のため、そのファイルをスキャンするという事実が好きではありません。代わりに、を"results.out"ファイルを書き込むメインループに組み込むことができないのはなぜですか?私がそうするなら、私はセグメンテーション違反を得る。これらに

for (i=1; i<=nrow; i++) { 
    fscanf(inp2, "%d %d", &dm1, &dm2); 
    fprintf(inp, "%d %d %d %d\n", i, dat[i], dm1, dm2); 
} 

:明確にするために、私は、コードに次の行を変更する意味

for (i=1; i<=nrow; i++) { 
    fprintf(inp, "%d %d %d %d\n", i, dat[i], dat2[i-1][0], dat2[i-1][1]); 
} 

私はまだ感謝C.

に非常に新しいんだと私は説明をみたいですたくさん! アミット

+0

これは私の友人のコードです。 –

+0

私は知っています。本当にお詫び申し上げます。私はあなたがそのすべてを読む必要はないと思う。おそらく最後のビットに集中するだけでしょうか? – Amit

答えて

4

は、私はあなたがこのように、datの配列インデックスから1を引くのを忘れて思う:

for (i=1; i<=nrow; i++) { 
    fscanf(inp2, "%d %d", &dm1, &dm2); 
    fprintf(inp, "%d %d %d %d\n", i, dat[i-1], dm1, dm2); 
} 
出て行くあなたは i <= nrowまでループしているので、これはセグメンテーションフォルトが発生した理由がある

、最後のループ反復でdatの境界の

+1

+1。 sidenote @Amit:あなたは 'dat2 [i] [j] = 0;'を行います。これは 'calloc()'がそれを行うので実際には必要ではありません。また、ファイルが正常に開かれたかどうかをチェックしないでください。 – Muggen

+0

@Muggen良い点。 –

+0

@Muggen:私はcallocが初期化することを知っていますが、必ずしも良い仕事をするとは限りません。 @Jacob:dat []は0からnrow(排他的)ではなく1からnrow(包括的)になります – Amit

2

あなたのコードには、Relkin(正確には)指摘されているもの以外にも何かがあると思います。

int nrow = NCH*(ns-1); 
dat = (int*) calloc(nrow, sizeof(int)); 

私の計算が正しいならば、それは以下の爆発的なアルゴリズムにdat[40419]

あるのでnrow == 81*(500-1)(== 40419):そう

k=1; 
while (k < nrow) { 
    for (j=0; j<250; j++) { 
     dat[k] = (j+1); 
     k++; 
    } 
    for (j=250; j>0; j--) { 
     dat[k] = j; 
     k++; 
    } 
} 

すべての内部forループ増加250によるk(両方ともwhileループごとに500ずつ増やします)、k < 40419です。これは、kが40001に達し、条件が満たされ、ループがもう一度進むというポイントがあることを意味します。現時点では、2番目のforループでは40419を超え、メモリに書き込むべきではありません。それを見て、再び私の数学をチェックしてください。

whileループの内部にいて、条件が偽装されていると、ループが自動的に終了するわけではありません。

+0

あなたは本当に正しいです。 'dat'は40419とされています。あなたは' while'ループのことについて確かに正しいと思います。なぜこの作品が...私は間違いなくsegfaultを報告すべきだろうと思う。 if文を追加してループを解除します。おそらくすべてが修正されます – Amit

+1

@Amit、これは 'Undefined Behaviour'です。何かが起きる可能性があります。どちらかの仕事、 'SegFault'、または他の人が言ったように'あなたのガールフレンドを妊娠させてください ' – Muggen

+0

@Muggen:LOL。私はまだそれを聞いたことはありませんが、私の金を作ることに感謝します。夜楽しくて笑う:) +1 – Amit