C Primer Plus(第六版)中文版 中的错误1

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define TSIZE 45
 5
 6 struct film {
 7     char title[TSIZE];
 8     int rating;
 9     struct film *next;
10 };
11 char * s_gets(char * st, int n);
12
13 int main(void)
14 {
15     struct film * head = NULL;
16     struct film * prev;
17     struct film * current;
18     char input[TSIZE];
19
20     puts("Enter first movie title:");
21     while(s_gets(input, TSIZE) != NULL && input[0] != ‘\0‘)
22     {
23         current = (struct film *) malloc(sizeof(struct film));
24         if(head == NULL)
25             head = current;
26         else
27             prev->next = current;
28         current->next = NULL;
29         strcpy(current->title, input);
30         puts("Enter your rating <0-10>:");
31         scanf("%d", &current->rating);
32         while(getchar() != ‘\n‘)
33             continue;
34         puts("Enter next movie title (empty line to stop):");
35         prev = current;
36     }
37
38     if(head == NULL)
39         printf("No data entered. ");
40     else
41         printf("Here is the movie list:\n");
42     current = head;
43     while(current != NULL)
44     {
45         printf("Movie: %s Rating: %d\n",
46                current->title, current->rating);
47         current = current->next;
48     }
49
50     current = head;
51     while(current != NULL)
52     {
53         current = head;
54         head = current->next;
55         free(current);
56     }
57     printf("Bye!\n");
58
59     return 0;
60 }
61
62 char * s_gets(char * st, int n)
63 {
64     char * ret_val;
65     char * find;
66
67     ret_val = fgets(st, n, stdin);
68     if(ret_val)
69     {
70         find = strchr(st, ‘\n‘);
71         if(find)
72             *find = ‘\0‘;
73         else
74             while(getchar() != ‘\n‘)
75                 continue;
76     }
77
78     return ret_val;
79 }

上面的代码来自《C Primer Plus》(第六版)中文版,第573-574页。

其中代码的第51行有错误。

不知道这个错误是印刷有错,还是原书有错。在此指出。

改正代码:

是将第51行的while(current != NULL)改为

while (head != NULL)就可以了。

原因如下:

将第51-56行代码之间添加一些输出,代码如下:

 1     while(current != NULL)
 2     {
 3         printf("current1 = %p\n", current);
 4         printf("head1 = %p\n\n",head);
 5         current = head;
 6         printf("current2 = %p\n", current);
 7         printf("head2 = %p\n\n",head);
 8         head = current->next;
 9         printf("current3 = %p\n", current);
10         printf("head3 = %p\n\n",head);
11         free(current);
12         printf("current4 = %p\n", current);
13         printf("head4 = %p\n\n",head);
14     }

输出结果如下:

从上面的输出结果可以看出,最后一个head2指针已经是00000000了,是一个指向未知地址的指针。所以再次释放一个current就会出错。

改正后的输出:

时间: 2024-10-24 06:50:09

C Primer Plus(第六版)中文版 中的错误1的相关文章

C++ Primer Plus 第六版 第16章 string类和标准模板库

1.string实际上是模板具体化basic_string<char> 的一个typedef,有默认参数,所以省略了初始化参数 2.size_type是一个依赖于实现的整形 string将string::npos定义为字符串的最大长度 3.string类的构造函数P656 4.对于c-风格字符串,3种输入方法:cin>>   cin.getline(),cin.get 对于string   ,2种输入方法:cin>>,getline(cin,string对象) 5.st

c++ primer plus(第6版)中文版 第九章编程练习答案

首先,说明下环境: linux:fedora14: IDE:eclipse: python:python2.7 python框架:django web服务器:apache web服务器的python模块:mod_wsgi 写在前面: 之前用的windows下面的xampp,写的php后台,现在想转向linux下面的python,跟以前一样,选择apache和eclipse作为自己的开发工具. eclipse的python配置, 参见之前的博客:http://blog.csdn.net/zy416

c++ primer plus(第6版)中文版 第十章编程练习答案

第十章编程练习答案 10.1为复习题5类提供定义,并演示 //10.1为复习题5类提供定义,并演示 #include <iostream> using namespace std; class BankAccount { string m_name; string m_num; unsigned m_balance; public: BankAccount (string name, string num, unsigned balance) { m_name = name; m_num =

c++ primer plus 第六版程序清单16.8 vect2.cpp 手打源码编译错误!!!

坚持手打源码,编译运行,但未每个程序均进行单步调试,昨天在VS2017上手打c++ primer plus 第六版程序清单16.8 vect2.cpp后编译出错: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------

c++ primer plus(第6版)中文版 第十三章编程练习答案

第十三章编程练习答案 13.1根据Cd基类,完成派生出一个Classic类,并测试 //13.1根据Cd基类,完成派生出一个Classic类,并测试 #include <iostream> #include <cstring> using namespace std; // base class class Cd { char performers[50]; char label[20]; int selections; // number of selections double

c++ primer plus(第6版)中文版 第八章编程练习答案

第八章编程练习答案 8.1编写一个输出字符串的函数,有一个默认参数表示输出次数,默认为1.(原题太扯啦,题意基础上小改动) //8.1编写一个输出字符串的函数,有一个默认参数表示输出次数,默认为1.(原题太扯啦,题意基础上小改动) #include <iostream> using namespace std; void show (const char* str, int time=1) { unsigned n=(time>0)?time:-time; for (unsigned i

c++ primer plus(第6版)中文版 第十二章编程练习答案

第十二章编程练习答案 12.1根据以下类声明,完成类,并编小程序使用它 //12.1根据以下类声明,完成类,并编小程序使用它 #include <iostream> #include <cstring> using namespace std; class Cow{ char name[20]; char * hobby; double weight; public: Cow(); Cow(const char * nm, const char * ho, double wt);

c++ primer plus(第6版)中文版 第七章编程练习答案

第七章编程练习答案 7.1编写一个程序,用户不停输入两数,直到有0出现为止,计算调和平均数 //7.1编写一个程序,用户不停输入两数,直到有0出现为止,计算调和平均数 #include <iostream> using namespace std; double average (unsigned x, unsigned y) { return (2.0 * x * y / (x + y)); } int main () { while (true) { unsigned x, y; cout

PMP(第六版)中的控制账户、规划包、工作包

控制账户是一个管理控制点,在该控制点上,把范围.预算和进度加以整合,并与挣值比较,以测量绩效.控制账户拥有2个或以上的工作包,但每个工作包只与一个控制账户关联. 规划包是一种低于控制账户而高于工作包的工作分解结构组件,工作内容已知,但详细的进度活动未知. 工作包是WBS 的最低层级是带有独特标识号的工作包.这些标识号为进行成本.进度和资源信息的逐层汇总提供了层级结构,构成账户编码. 以上总结参考PMPBOK(第六版) 原文地址:https://www.cnblogs.com/Siny0/p/11