2011-07-13 43 views
0

我一直在爲此撓了幾個小時。這將數據從文本文件讀入結構中(每行有四個字符串,每行代表一個新學生)。我在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; 
} 

是什麼導致這個seg故障?

由於提前,

格斯

+2

重寫你的內環儘管不是你的段錯誤的根源,你使用的realloc可能會導致內存泄漏的方式時的realloc不能分配更多的內存,因爲它會返回NULL,並且你會丟失指向前一個緩衝區的指針 – Vitor

回答

3

如果陣列有studcount元素,然後studentArray[studcount]是過去的數組的末尾,寫有不允許的。訪問的有效元素是0studcount-1。您應該將studentArray[studcount]替換爲studentArray[studcount-1]以寫入最後一個元素。

請注意,這樣做會給你一個studcount值,因爲數組的最後一個元素總是爲空或不完整,所以在循環完成時1的值太大。

正如pmg在評論中提到的,另一種解決方案是將studcount初始化爲0,這將解決上述兩個問題,但是之後您需要確保在編寫新元素之前至少爲空間分配至少studcount+1元素。

+1

+1或者,最好將'studcount'初始化爲0 – pmg

+0

謝謝!這做到了。 – 9us

0

你的循環和scanf結構如下錯誤..

首先你讀一個字符串(scanf在while條件),那麼一個int(word == 1),然後另一個字符串(而再次條件,word == 2),另一個字符串(同時條件再次爲word == 3),最後是另一個字符串和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

一個問題:sscanf不記得字符串中的位置,對吧?所以每次我打電話給sscanf,它都會從頭開始,那麼我將如何掃描字符串中的第二個單詞? – 9us

+0

嗯......是的,你是對的。最好一次性完成。修正答案:) – pmg