《 C Primer Plus (第六版)中文版 》 书中的一处勘误
来源:互联网 发布:黄金买卖交易软件 编辑:程序博客网 时间:2024/06/10 16:08
出错的地方:
第17章高级数据表示
17.2.1 使用链表
17.2 films2.c程序
第574页
下面是程序清单,红色框内的代码是出错的地方。
作者的本意是想把current指向链表的开头结点,head指向下个结点,然后free当前结点,并判断是否是最后一个结点,不是的话就循环,保存下个结点的head的值再赋给curent ,head指向下一个结点,再free当前结点。。。依此类推,直到最后一个结点NULL, 循环结束。
表面看这个逻辑没任何问题。但是由于逻辑上的不严谨,这里程序产生了bug。
这段代码有两个很明显的错误,分析如下:
第一,先不理会这段代码循环了多少次。循环的最后一行free 了current指针 ,然后回过头来再判断current是否为NULL.注意,这个地方在使用野指针了。因为free之后,原先申请到的内存空间已经返回给系统了,所以current已经指向一个不合法的内存空间。此时对current的任何操作都是错误的。
第二,因为是先free current再判断current是否为NULL,所以free的次数会比malloc多一次。
执行上面程序,运行结果显示是段错误,我们来分析为什么会产生段错误。
假设一共有3个结点。循环第一次后,head指向第2个结点,第1个结点被free掉。
循环第二次后,head指向第3个结点,第2个结点被free掉。
循环第三次后,head指向第4个结点,是不存在的结点,为NULL,第3个结点被free掉。
循环第四次,current指向第4个结点NULL,head = current -> next 变成了这样子
head = NULL -> next。然而NULL是系统定义的0地址,我们知道计算机的低地址空间是不允许被访问的。这里试图操作内存低地址空间所以就产生了段错误。
虽然文章后面也讲了films2.c程序的一些不足。但是上面写到的错误明显是作者的不细心造成的。(也有可能是翻译错了,因为英文版的书我没有看过。)
下面修改之后的代码:
// 释放内存
current = head;
while(current != NULL)
{
head = current -> next;
free(current);
current = head;
}
最后说一句,很多程序的BUG都是来源于逻辑上的不严谨,还有就是没有养成好的编程习惯。
- 《 C Primer Plus (第六版)中文版 》 书中的一处勘误
- C Primer Plus(第五版)中文版勘误
- C++ primer plus 第六版中文版 18.1
- C++ primer plus 第六版中文版 18.2
- C++ primer plus 第六版中文版 18.3
- C++ primer plus 第六版中文版--目录
- 【读书笔记:C++ primer plus 第六版 中文版】第14章 C++中的代码重用
- C Primer Plus (第六版)中文版 第十章 编程练习答案
- C Primer Plus (第六版)中文版 第七章 编程练习答案
- C Primer Plus(第5版)中文版
- C primer plus 第五版 中文版 勘误表
- C Primer Plus(第五版)中文版.pdf
- C++ Primer Plus(第六版)读书笔记(一)
- 关于《C++ primer plus 第六版》中文版的答案说明
- c++primer plus 第六版 练习答案
- 【C Primer Plus 第六版】笔记
- c++Primer Plus第六版练习题答案
- C Primer Plus 中文版 前言
- 技术如何秒懂你?阿里百万级QPS资源调度系统揭秘
- python3.x中的生成器generator调用next方法
- AtCoder Regular Contest 068
- Bootstrap 列表
- 小程序推广思路整理
- 《 C Primer Plus (第六版)中文版 》 书中的一处勘误
- Bootstrap使用常见问题
- 网络结构与同态设计
- RPM包下载 网站
- Java并发编程:volatile关键字解析
- 在小程序开发的新风口 看华为云如何助立创科技抢占市场红利
- rtmp源码分析
- ubuntu下latex中文环境配置
- jpeg