0

私はこれについて何時間も頭を悩ませてきました。これは、テキスト ファイルから構造体にデータを読み取ります (各行には 4 つの文字列があり、各行は新しい学生を表します)。realloc でセグ フォールトが発生しています (終わり近く)。ポインターが malloc/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;
}

このセグフォルトの原因は何ですか?

前もって感謝します、

ガス

4

2 に答える 2

3

配列にstudcount要素がある場合studentArray[studcount]は、配列の末尾を超えているため、そこへの書き込みは許可されていません。アクセスする有効な要素は0tostudcount-1です。最後の要素に書き込むには、どこでもstudentArray[studcount]置き換える必要があります。studentArray[studcount-1]

このようにすると、配列の最後の要素は常に空または不完全であるため、ループが完了するまでにstudcount値が大きすぎることに注意してください。1

コメントで pmg が述べたように、別の解決策は 0 に初期化することです。これにより、上記の問題の両方が修正されますが、新しい要素を書き込む前にstudcount、少なくとも要素に余裕を割り当てる必要があります。studcount+1

于 2011-07-13T14:06:07.603 に答える
0

ループとscanfの構造が間違っているようです。

scanf最初に文字列( while条件)、次にint(word== 1)、次に別の文字列(while条件、word== 2)、別の文字列(while条件、word== 3)、最後に別の文字列を読み取ります文字列とa 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 */;
}
于 2011-07-13T14:17:47.667 に答える