2012-01-01 12 views
3

私は単純な分子動力学プログラムを実装したいと考えています。私の最初のステップは、タイプ、id番号、3次元位置ベクトル、3次元速度ベクトルを持つ一連の原子としてシステムを定義することです。以下は、私がそうすることを書いたプログラムは次のとおりです。ここで最後のコード行にSegフォルトがあります

FILE *init; 

static int randomVelocity(void) 
{ 
    return rand()/RAND_MAX - 0.5; 
} 


int main(int argc, char *argv[]) 
{ 

    int iType; 
    int iID; 
    int i; 
    double* pdPosition; 
    double* pdVelocity; 
    char* line; 
    Atom* poAtoms; 
    int count = 0; 

    init = fopen("newdat.txt", "r+"); 
    srand((unsigned)time(NULL)); 
    line = malloc(81*sizeof(char)); 
    while (fgets(line, 80, init) != NULL)  
    { 
     char* tok1; 
     char* tok2; 
     char* tok3; 
     char* tok4; 
     tok1 = strtok(line, " \t"); 
     if ((tok1 == NULL) || (tok1[0] == '*')) 
     { 
       break; 
     } 
     tok2 = strtok(NULL, " \t"); 
     tok3 = strtok(NULL, " \t"); 
     tok4 = strtok(NULL, " \t"); 
     iType = atoi(tok1); 
     iID = count; 
     pdPosition = (double*)malloc(3*sizeof(double)); 
     pdVelocity = (double*)malloc(3*sizeof(double));  
     pdPosition[0] = atof(tok2); 
     pdPosition[1] = atof(tok3); 
     pdPosition[2] = atof(tok4); 
     pdVelocity[0] = randomVelocity(); 
     pdVelocity[1] = randomVelocity();  
     pdVelocity[2] = randomVelocity(); 
     poAtoms[count] = Atom_new(iType, iID, pdPosition, pdVelocity); 
     count++; 
    } 

    for (i = 0; i < count; i++) 
    { 
     Atom_print(poAtoms[i]); 
     Atom_free(poAtoms[i]); 
    } 

    free(line); 
    return 0; 
} 

は、ヘッダファイルatom.hです:

/**** atom.h ****/ 


typedef struct Atom_str *Atom; 

Atom Atom_new(int iType, int iID, double* adPosition, double* adVelocity); 

void Atom_free(Atom oAtom); 

void Atom_print(Atom oAtom); 

とテスト入力ファイル:

1 5 7 9 
2 12 13 14 

プログラム私はそれを実行すると、期待される出力がsegフォールトに続く。私はGDBデバッガを使用していますが、segフォルトはreturn文の後の最後のコード行で発生するようです。それはメモリ管理の問題ですか?

+0

これらのタイプは、多くの場合、メモリの破損に関連する参考になります。 GDBのクラッシュの後に "bt"とタイプしてスタックトレースがあるかどうか確認し、もしそうならポストできますか?またはValgrindを使用します。 –

+0

これはあなたが参照していたスタックトレースですか? #0 0x0804b3fd? () の#1 0x00000001 () #2 0xffffd8b4? () #3 0xffffd8bc? () #4 0x00722828? () #5 0x00000000? () – user1125353

答えて

6

あなたはpoAtomsため決してmalloc EDメモリをしました。初期化されていないポインタポイントがどこにあっても、segfaultが簡単に発生する可能性があります。

ファイルを読み始める前に、あなたには、いくつかのスペースを割り当てる必要があり、

unsigned expected_count = 2; // for the test input file, would be much larger in real runs 
poAtoms = malloc(expected_count*sizeof(*poAtoms)); 

そして、あなたが割り当てられたメモリを過ぎて書いていないことを読んで、ループ内でチェックする必要があります。

poAtoms[count] = Atom_new(iType, iID, pdPosition, pdVelocity); 

前に、poAtomsのために割り当てられたスペースが既に使用されている場合、それが失敗した場合、reallocとより取得しようと、

if (expected_count <= count) 
    { 
     expected_count *= 2; // double the space, could also be a smaller growth factor 
     Atom *temp = realloc(poAtoms, expected_count*sizeof(*poAtoms)); 
     if (temp == NULL) 
     { 
      perror("Reallocation failed, exiting\n"); 
      exit(EXIT_FAILURE); 
     } 
     poAtoms = temp; 
    } 

をチェックを入れ、あなたがそれを修正する方法を知っている場合を除き中止。再割り当てが成功すれば、新しい原子の収集を続けることができます。

+0

あなたの返信をありがとう、Daniel!私は私の原子のコードを提供しています。cファイル:struct Atom_str { int iType; int iID; double * pdPosition; double * pdVelocity; }; Atom_new(int iType、int iID、double * adPosition、double * adVelocity) { Atom oAtom; oAtom =(Atom)malloc(sizeof(struct Atom_str)); if(oAtom == NULL) NULLを返します。 oAtom-> iType = iType; oAtom-> iID = iID; oAtom-> pdPosition = adPosition; oAtom-> pdVelocity = adVelocity; oAtom-> pdVelocity = adVelocity; return oAtom; } – user1125353

+0

私は奇妙なフォーマットをして申し訳ありませんが、私が言ったことは、 "oAtom =(Atom)malloc(sizeof(struct Atom_str));)という行を使って、私は十分な記憶を整えていないでしょうか? – user1125353

+0

これは、Atom * poAtoms;宣言とpoAtoms [count] = Atom_new(iType、iID、pdPosition、pdVelocity);という宣言の間に 'poAtoms'の記述はありませんので、ここでは無関係です。したがって、 'poAtoms'は、誤ってスタック上の位置を占めていたビットが何であっても指し示しています。それが' Atom_new'の戻り値が書き込まれる場所です。あなたの場合、それはプログラムの終了コードの一部を上書きしたようです。 –

0

if条件ではtok1 [0]とは何ですか?あなたはtok1 [[0]を印刷しようとしたときに返されるかチェックされるstrtokの小さなコードスニペットを調べましたか?

0

入力ファイルに1 5 7 9が何を表すのか説明できますか? i型のidと速度です。 もしそうなら、それらをハイフンで操作し区別し、各値をstrtokでNULLとして抽出することができます。また、fgetsがNULLを追加しているかどうかを確認するか、おそらくEnd of lineの場合はチェックインしようとしているかもしれません。私はそれはあなたが間違っている場所であることを伐採腸を持っている、またはあなたが嘆願は、あなたの入力ファイルを説明できるかどうかは問題の

+0

あなたの返信ありがとう! 1はアトムタイプです。 5,7および9はそれぞれ位置ベクトルのx、yおよびz成分でなければなりません。 (速度ベクトルの3つの要素は、乱数ジェネレータによって提供されます。)私のコードのif(tok1 [0] == '*')部分は、入力ファイルにコメントがあり、 '*'で区切られていると仮定しています。 ..しかし、おそらくもう少し考えてみる必要があります! :) – user1125353

関連する問題