2011-07-13 13 views
0

私は数時間頭を掻き回してきました。これは、テキストファイルから構造体にデータを読み込みます(各行には4つの文字列があり、各行は新しい生徒を表します)。私はrealloc(最後の近く)にsegフォルトを得ています。私はポインタがmalloc/reallocとどのようにやり取りしているのか理解していないとの疑いがあります。構造体の配列にreallocを使用する

struct student* createInitialStudentArray(FILE *fp) { 
    char buf[20+1] = {0}; 
    int word = 1, studcount = 1; 
    struct student* studentArray = malloc(sizeof(struct student)); 
    assert(studentArray != NULL); 
    while (fscanf(fp, " %20s", buf) != EOF) { 
     if (word % 4 == 1) { 
      sscanf(buf, "%4d", &studentArray[studcount].studentID); 
      word++; 
     } 
     else if (word % 4 == 2) { 
      strcpy(studentArray[studcount].lastName, buf); 
      word++; 
     } 
     else if (word % 4 == 3) { 
      strcpy(studentArray[studcount].firstName, buf); 
      word++; 
     } 
     else if (word % 4 == 0) { 
      sscanf(buf, "%10lld", &studentArray[studcount].phoneNumber); 
      word = 1; 
      studcount++; 
      studentArray = realloc(studentArray, studcount * sizeof(struct student)); 
      assert(studentArray != NULL); 
     } 
    } 

    return studentArray; 
} 

このセグフォルトの原因は何ですか?あなたの配列がstudcountの要素を持っている場合は、事前に

おかげで、

のGus

+2

であなたの内側のループを書き換えたい

のreallocは、より多くのメモリを割り当てることができないとき、あなたはreallocのを使用している方法は、メモリリークにつながる可能性なぜなら、NULLを返して、前のバッファへのポインタを失うからです。 – Vitor

答えて

3

は、その後、studentArray[studcount]は、配列の最後を過ぎて、そしてそこに書き込みが許可されていません。アクセスする有効な要素は0studcount-1です。最後の要素に書き込むには、studentArray[studcount]studentArray[studcount-1]に置き換えてください。

ループの最後の要素が常に空または不完全であるため、このようにするとループが完了したときにの値が1と大きすぎることになります。

コメントのpmgで説明したように、もう1つの解決策は、上記の両方の問題を解決するstudcountを0に初期化することですが、新しいものを書き込む前に少なくともstudcount+1個分の領域を確保する必要があります。

+1

+1または、 'studcount'を0に初期化するのが良いです。 – pmg

+0

ありがとう!これはそれでした。 – 9us

0

あなたのループやscanf構造が間違って見えます。..

まずあなたは、文字列(while条件でscanf)、INT(word == 1)、その後、別の文字列(条件再びしばらく、wordを読みます== 2)、別の文字列(再び条件を満たす間、word == 3)、そして最後にもう1つの文字列とlong long intword == 4)。私はあなたのセグメンテーションフォルトの根本的な原因されていないにも関わらず、スイッチ

/* pseudo-code */ 
while (fgets(buf, sizeof buf, stdin)) { 
    /* realloc here */ 
    chk = sscanf(buf, "%4d%20s%20s%10lld", 
       &studentArray[studcount].studentID, 
       studentArray[studcount].lastName, 
       studentArray[studcount].firstName, 
       &studentArray[studcount].phoneNumber); 
    if (chk != 4) /* deal with error */; 
} 
+0

ありがとうございました。 – 9us

+0

1つの問題:sscanfは文字列内の場所を覚えていません。だから私はsscanfを呼び出すたびに、それは最初から始まるので、文字列の2番目の単語をどのようにスキャンするのでしょうか? – 9us

+0

Hmmm ...はい、あなたは正しいです。それはすべて1回だけです。回答を修正する:) – pmg

関連する問題