C语言的那些坑(C Primer Plus第六版 17.2程序释放链表bug)
2017-11-30 10:25
369 查看
第三个坑 C Primer Plus第六版 17.2程序释放链表bug
C Primer Plus是一本很好的C语言书,里面的代码丰富详细,对初学者的晋升有很大帮助,但问题在于代码也都是人编写的,出现bug也是很正常的。善于发现bug也是一种能力。
话不多说 实锤
下面是书中的源代码
这是一段典型的尾插法创建链表然后并对其遍历的代码。问题出现在主函数最后部分释放链表的时候。
将current指向了表头,然后依次释放直到next指针为null为止。但当代码执行后会发现这里会报错,问题在于,先free了current,那么current->next的值自然也跟随释放了,此时current->next不再指向下一结点。所以current = current->next也就没有了意义。
所以此处正确的做法是创建一个临时变量,在释放current之前将它的下一结点保存下来。如下:
C Primer Plus是一本很好的C语言书,里面的代码丰富详细,对初学者的晋升有很大帮助,但问题在于代码也都是人编写的,出现bug也是很正常的。善于发现bug也是一种能力。
话不多说 实锤
下面是书中的源代码
#include <stdio.h> #include <stdlib.h> /* has the malloc prototype */ #include <string.h> /* has the strcpy prototype */ #define TSIZE 45 /* size of array to hold title */ struct film { char title[TSIZE]; int rating; struct film * next; /* points to next struct in list */ }; char * s_gets(char * st, int n); int main(void) { struct film * head = NULL; struct film * prev, * current; char input[TSIZE]; /* Gather and store information */ puts("Enter first movie title:"); while (s_gets(input, TSIZE) != NULL && input[0] != '\0') { current = (struct film *) malloc(sizeof(struct film)); if (head == NULL) /* first structure */ head = current; else /* subsequent structures */ prev->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):"); prev = current; } /* Show list of movies */ 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; } /* Program done, so free allocated memory */ current = head; while (current != NULL) { free(current); current = current->next; } printf("Bye!\n"); return 0; } char * s_gets(char * st, int n) { char * ret_val; char * find; ret_val = fgets(st, n, stdin); if (ret_val) { find = strchr(st, '\n'); // look for newline if (find) // if the address is not NULL, *find = '\0'; // place a null character there else while (getchar() != '\n') continue; // dispose of rest of line } return ret_val; }
这是一段典型的尾插法创建链表然后并对其遍历的代码。问题出现在主函数最后部分释放链表的时候。
/* Program done, so free allocated memory */ current = head; while (current != NULL) { free(current); current = current->next; }
将current指向了表头,然后依次释放直到next指针为null为止。但当代码执行后会发现这里会报错,问题在于,先free了current,那么current->next的值自然也跟随释放了,此时current->next不再指向下一结点。所以current = current->next也就没有了意义。
所以此处正确的做法是创建一个临时变量,在释放current之前将它的下一结点保存下来。如下:
while (current != NULL) { struct film * tmp = current->next; free(current); current = tmp; }
相关文章推荐
- C++primer plus第六版课后编程题答案17.2
- C++ Primer Plus第六版编程练习12.4解答
- c++ Primer Plus(第六版)第十八章习题,写代码之路
- C++ Primer Plus 第六版课后编程答案 2.6-2.7
- 《C++ Primer Plus(第六版)》(46)(STL函数汇总)
- C++ primer plus第六版课后编程练习答案:7.1
- C primer plus(第五版)第十七章链表list.h,list.c,films3.c编译警告原因
- C++ Primer Plus 第六版 第三章编程题解题writeup
- c++ Primer Plus(第六版)第九章编程练习之路
- C语言的那些小秘密之【链表(二)】
- 【学习C++】C++ Primer Plus (第六版)第十一章编程练习1-7
- C Primer Plus 第十三章程序清单……2015.5.15
- C++ primer plus第六版课后编程练习答案:6.2
- 【读书笔记:C++ primer plus 第六版 中文版】第4章 复合类型
- 【读书笔记:C++ primer plus 第六版 中文版】第5章 循环和关系表达式
- 【读书笔记:C++ primer plus 第六版 中文版】第8章 函数探幽
- C++primer plus第六版课后编程题答案 6.9
- C语言的那些小秘密之链表(三)
- C++ primer plus(第六版)学习笔记、习题答案(3)
- 一个正确的c语言链表代码(中间也有些bug)