读《C Prime Plus》有感1——C动态链表释放内存问题

来源:互联网 发布:linux 守护进程死掉 编辑:程序博客网 时间:2024/05/22 01:53

          在该书第五版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;}<strong>/*任务完成,因此释放所分配空间*/current = head;while(head != NULL) {free(current);current = current->next;}</strong>printf("Bye!\n");return 0;}

           在vc++6.0中会引发断言失败,调试后发现问题处在最后一部分,及“任务完成,因此释放所分配内存空间部分”(文中已加粗),经过调试后,发现问题如下:

        此部分开始用current指向head,while循环中首先free(current),既然已经释放掉current内存空间,下一步如何让current指向current->next?所以出现断言失败。修改方法要使用另外一个hou先保存当前需释放节点的下一个节点的指针即可。

<strong>/*任务已完成,因此释放所分配的内存*/current = head;hou = current->next;while(hou != NULL) {printf("HERE!\n");free(current);current = hou;hou = current->next;}free(current);</strong>

          《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