在該書第五版17章“進階資料表示”中,程式清單17.2給出給出如下代碼:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define TSIZE 45#define LEN sizeof(struct film)struct film {char title[TSIZE];int rating;struct film *next;};int main() {struct film *head = NULL;struct film *pre, *current, *hou;char input[TSIZE];/*收集並儲存資訊*/puts("Enter first movie title:");while(gets(input) != NULL && input[0] != '\0'){current = (struct film*)malloc(LEN);if(head == NULL) {head = current;}else {pre->next = current;}current->next = NULL;strcpy(current->title, input);puts("Enter your rating<0-10>:");scanf("%d", ¤t->rating);while(getchar()!='\n')continue;puts("Enter next movie title(empty line to stop):");pre = current;}/*給齣電影列表*/if(head == NULL) {printf("No data entered.");}else{printf("Here is the movie list:\n");}current = head;while(current != NULL) {printf("Movie:%s Rating:%d\n", current->title, current->rating);current = current->next;}/*任務完成,因此釋放所分配空間*/current = head;while(head != NULL) {free(current);current = current->next;}printf("Bye!\n");return 0;}
在vc++6.0中會引發宣告失敗,調試後發現問題處在最後一部分,及“任務完成,因此釋放所分配記憶體空間部分”(文中已加粗),經過調試後,發現問題如下:
此部分開始用current指向head,while迴圈中首先free(current),既然已經釋放掉current記憶體空間,下一步如何讓current指向current->next?所以出現宣告失敗。修改方法要使用另外一個hou先儲存當前需釋放節點的下一個節點的指標即可。
/*任務已完成,因此釋放所分配的記憶體*/current = head;hou = current->next;while(hou != NULL) {printf("HERE!\n");free(current);current = hou;hou = current->next;}free(current);
《C Primer Plus》確實是一本偉大的書,但盡信書不如無書,作者Stephen Prata可能也希望他的讀者能找到些許他在不經意中出現的小錯誤吧!
補充,隨後在該書的程式清單17.5中就驗證了本人的想法,作者給出了一個清空鏈表的函數,基本想法一致,代碼如下:
/*釋放由malloc()分配的記憶體*//*把列表指標置為NULL*/void EmptyTheList(List *plist){Node* psave;while(*plist != NULL) {psave = (*plist)->next;free(*plist);*plist = psave;}}
相關連結:http://hi.baidu.com/mayadong7349/item/b88d0630a3d9043d2e20c4c2