接到出版社通知,《0bug-C/C++商用工程之道》第一版已告售罄,正准备第二次印刷,因此,我最近虽然工作很忙,也还是赶着把勘误表做出来,以便在第二次印刷时修订。
说来惭愧,本书虽然名为《0bug》,还是被各位读者找出来差不多20来处bug,对于较大的问题,我前期已经分别写了博文一一详细说明,这里给出一个汇总表,方便各位读者查阅。
总计21个bug,其中严重bug 5个,占23.8%,一般bug 16个,占76.2%。
编号 | 页码 | 问题性质 | 严重程度 | 问题修订描述 |
1 | P26 | 个人知识不足 | 严重 | 主要是针对32位操作系统的内存管理论述不精确,没有考虑到Linux的内存使用情况。我重新修订了原文。由于太长,此处略,有兴趣读者请参考这篇博文:“关于《0 bug -- C/C++商用工程之道》的一处bug ”http://tonyxiaohome.blog.51cto.com/925273/254129 |
2 | P40 | 笔误 | 一般 | 有时候,由于业务需要,A计算机向B计算机… |
3 | P41 | 举例有误,论述不清 | 严重 | 原文太长,此处略,详见博文“关于《0bug》一书锁描述的一处修订 ”:http://tonyxiaohome.blog.51cto.com/925273/338230 |
4 | P53 | 笔误 | 一般 | “但要时支持100000用户”应该是“但要是支持100000用户” |
5 | P59 | 笔误 | 一般 | 程序段落第五行 “如果写入为0,表示现在不能写” |
6 | P84 | 笔误 | 一般 | class CmutexLock(此处m应该大写) { public: ? ? CMutexLock(void); } |
7 | P87 | 笔误 | 一般 | CA是一个传输模块,它使用的CBuffer建议就定名为CABuffer, 相应的,CB就是CBBuffer,这是为了以后的重用降低重名率。 |
8 | P91 | 原例子感觉说明不充分,重新举例 | 重要 | 最上面阴影部分重新举例,改为下面一段话: 另外,很多开源代码中喜欢使用do{…}while(0);作为定义宏的包容符,笔者对此也持保留意见,把一个明显为循环语句的do{}while()结构,转义为宏包容符,这属于典型的一语多义,不是很熟悉C编程规约的程序员,很容易看错导致误读,这也是笔者不用do{}while()的理由之一。 |
9 | P102 | 笔误 | 一般 | 2.小标题 改为:“用聚合不用继承” |
10 | P115 | 笔误 | 一般 | 第五行 但不保证mem cache位于… |
11 | P118 | 笔误 | 一般 | 倒数几行代码示例,中间改为A* pa; #include "a.h" class B { A* pa; }; |
12 | P151 | 笔误 | 一般 | r应加括号,安全一点。 #define Get_Circular_Area(r) (PI*((double)(r))*((double)r)) |
13 | P179 | 笔误 | 一般 | 头文件表有重复定义,更正如下 //通用包含 #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <time.h> #include <fcntl.h> #include <signal.h> #ifdef WIN32 //windows下特定包含 #include <conio.h> #include <windows.h> #include <process.h> #include <winsock.h> #else //Linux Unix下特定包含 #include <unistd.h> #include <errno.h> #include <pthread.h> #include <fcntl.h> #include <unistd.h> #include <netinet/in.h> #include <string.h> #include <sys/time.h> #include <arpa/inet.h> #include <errno.h> #include <termios.h> #include <netdb.h> #include <getopt.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #endif |
14 | P197 | 程序bug,平均值计算公式使用错误 | 严重 | 计算统计平均值,代码有bug 改为如下段落 //基数统计平均值模块 typedef struct _COUNT_ { SCountSub m_Sub; //ΔX计算 unsigned long m_Sum; //统计平均值 unsigned long m_nAllCount; //总累加器 unsigned long m_nTimes; //累加次数 }SCount;//初始化 void SCountReset(SCount& Count,unsigned long n) { Count.m_nAllCount=0; Count.m_nTimes=0; Count.m_Sum=n; Count.m_Sub.m_lXBegin=0; Count.m_Sub.m_lXEnd=0; } //计算统计平均值 unsigned long SCountSum(SCount& Count) { unsigned long X=SCountSubGetX(Count.m_Sub); if(0==Count.m_Sum) Count.m_Sum=X; //初值如果为,则直接赋值,避免误差 else //计算统计平均值 { Count.m_nAllCount+=X; Count.m_nTimes++; if(Count.m_nTimes) //此处未考虑溢出误差 Count.m_Sum=(Count.m_nAllCount/Count.m_nTimes); } return Count.m_Sum; } |
15 | P199 | 进一步加强说明 | 一般 | 主要是针对随机数论述自己不太满意,因此重新加强了说明。详见博文“关于《0bug》一书随机数的一处修订”:http://tonyxiaohome.blog.51cto.com/925273/338233 |
16 | P268 | 7.1.1 不泄漏 由于C和C++语言中,内存的申请和释放,一定是二元动作,需要程序员显式地调用相关函数,对称地完成内存操作,才能保证不泄漏内存。 这对很多情况下的程序开发,提出了较高的要求,笔者前文花了大量的篇幅,向大家介绍二元动作操作的常见手法,以期避免内存泄漏等bug。 不过,这些动作一般都是程序员的行为,我们知道,程序员是人,是人就有可能犯错误,纯粹的手工操作规范,并不足以杜绝内存bug的产生。 于是笔者就设想,如果在C和C++传统的内存管理机制之外,我们自行构建一种内存的管理机制,能在程序员忘了释放内存时,主动替其释放,则可望大大减少内存相关的bug。因此,内存池的第一个设计目标,是主动替程序员完善二元动作,确保“不泄漏内存”。 针对这个问题,笔者通常的解决方案是内部建立一套登记机制,记录所有在用的内存块,当程序退出时,如果发现还有内存块在内存池中处于激活状态,即表示有内存块忘了释放,内存池会帮助程序员释放内存,避免产生内存泄漏。 | ||
17 | P313 | 笔误 | 一般 | 指针注册方法程序代码第一行 oid应该为void |
18 | P327 | 笔误 | 一般 | 第三行 GetFirstLenght应该为GetFirstLengh |
19 | P391 | 程序bug | 严重 | 关于动态队列类bool CTonyXiaoMemoryQueue::DeleteFirst(void)里面隐藏的一个bug问题,做了修订,原文太长,此处略,详见博文“100402关于《0bug-C/C++商用工程之道》的读者来信回复 ”http://tonyxiaohome.blog.51cto.com/925273/290716 |
20 | P432 | 笔误 | 一般 | 第四行 #else要换行,另起一行 |
21 | Modeify拼写错误 | 笔误 | 一般 | 请全局查找一下 所有的Modeify改为Modify |
本文转自 tonyxiaohome 51CTO博客,原文链接:http://blog.51cto.com/tonyxiaohome/338234 ,如需转载请自行联系原作者