版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+低级错误案例目录1 前言22 【低级错误】 22.1 数组下标访问越界 222变量必须在定义时同时未初始化 32.3 在循环条件中求循环次数或者大小,影响性能 32.4 混淆 “ =与 “ =” 32.5 指针使用前必须做非空检查判断 42.6 宏定义未充分封装替换参数 52.7 case语句遗漏 break或缺少 default分支条件 52.8 未判断函数返回值 62.9 判断无符号数是否小于 0 63 【1级错误】73.1 使用野指针73.2 内存拷贝忽略字符串结尾标志 0'73.3 分支流程未释放动态申请的内存 83.4 数据类型不一致,变量或参数赋值出错 93.5 循环体
2、内改写循环变量 93.6 魔鬼数字103.7 对只读参数未加 const修饰 103.8 各种资源句柄没有释放 103.9 变量名、枚举名、常量名字面意思、注释含义与使用时相反 113.10 所有的可能抛异常的地方都要有捕获114 【2级错误】 124.1 循环变量数据类型太小 124.2 函数局部变量或参数过大,堆栈溢出121前言本规范用于规范C+项目组中各个局点交付版本的代码交付质量。保证系统的质量,保证系统有效的运行。提高编码工作效率,规避低级错误出现,指导代码评审活动开展工作。代码案例:2【低级错误】2.1数组下标访问越界(1 )数组下标根据计算得出i = a - b ;arrayi
3、= 0 ; /使用前应该检查i的合法性(2 )数组下标通过函数得出void mai n()int i, b10;1get In dex(&i);bi = 0; /使用前应该检查i的合法性(3)数组下标是循环变量void mai n()int i, max, b10;getMax(&max);for (i = 0; i < max; i+) /使用前应该检查 max的合法性bi = 0;2.2变量在定义时同时未初始化错误:int i ;/没有赋初始值prin tf("i= %d n ”,i);随机分配一个值:-858993460自动对象的存储分配发生在定义它的函数
4、被调用时,未初始话化的自动对象包含一个随机的位模式,是该存储区上次被使用的结果,值是不确定的。正确:int i = 0 ; /定义的同时赋初始值 02.3在循环条件中求循环次数或者大小,影响性能错误:for (int i=0; i<(i nt)attributeList.le ngth(); i+) 正确:int tmp_iListLe ngth = attributeList.le ngth() for (in t i=0; i< tmp_iListLe ngth; i+) 此案例发生在广东移动业务中,数据量达5000千万用户,影响性能是秒级的,在呼叫业务中用户是不可接受的。2.
5、4 混淆“=” “=”如下例子的循环判断条件中,将”=”误写成”=”,导致死循环。错误:Bool result = True;while(result = True)result = execF un c();wait();正确:while(True = result)result = execF un c();wait();编程规范要求将常量写在等号左边(如" True = result ”),确保编译时即可发现错误。2.5指针使用前必须做非空检查判断CAppService* tmp_pAppService=dyn amic_cast<CAppService*>(m_p
6、AppSessi on->getAppServiceBase();m_pLogger = tmp_pAppService->getLogger();/tmp_pAppService指针有可能为空,那么就会core掉正确:CAppService* tmp_pAppService = NULL;tmp_pAppService =dyn amic_cast<CAppService*>(m_pAppSessi on->getAppServiceBase();if (tmp_pAppService != NULL)m_pLogger = tmp_pAppService-&g
7、t;getLogger();else错误处理;类似数据库查询对结果集读取也应该先检查再使用如:ENIP : IMemRecordSet * tmp_pRecordSet = t_dataSetRef . getRecordSet ();if ( NULL =tmp_pRecordSet )ELOG( "RecordSet pointer is NULL.");t_bHasRecord = ENIP : False ;else if (tmp_pRecordSet -> eof ()LOG( "No record found in LostCallServic
8、eBlackList.");t_bHasRecord = ENIP : False ;在函数或方法中涉及指针或引用传递须遵循以下规则:1. 函数属于私有类型,如果内部不做检查,外部调用时必须做检查(函数内部需 要加以说明);如果内部做了检查,外部调用时可以不做检查(调用时需要加以说明);2. 函数属于公有类型,函数内部必须做检查,在外部调用时可以不做检查(调用时需要加以说明);2.6宏定义未充分圭寸装替换参数错误:#defi ne RECT_SIZE (X*Y)X = len gth + 1;Y = width + 1;最终结果为length + width + 1,与预计不符合正确
9、:#defi ne RECT_SIZE (X)*(Y)2.7 case语句遗漏break或缺少default分支条件错误:case WM_CLOSE:Close(); /遗漏break语句,执行完关闭后,重新使用已释放资源case WM_READ:Read();break;正确:switch ()case WM_CLOSE:Close();break;case WM_READ:Read();break;default: /不要遗漏default 语句2.8未判断函数返回值错误:/处理计费矩阵查询结果doMatrixA nalysis(request, resp on se)以上代码忽略了函数的
10、返回值检查,调用计费矩阵分析方法,函数原型如下:int doMatrixAnalysis( const TiChargeMatrixAnalysisReqArg& reqArg ,TiChargeMatrixA nalysisResArg& resArg );如此,有可能在后续计费执行过程出现严重错误正确:if (success = doMatrixAnalysis( request , response)计费矩阵分析成功elseELOG( "doMatrixAnalysis failure and release the call");t_blsError
11、 = ENIP : True ; /计费矩阵分析失败,异常退岀break ;2.9判断无符号数是否小于0un sig ned char c;/c赋值为具体的循环次数,会导致死循环while(c->=0)/do someth ing 3【1级错误】3.1使用野指针(1 )使用未分配空间的指针void func()char *p;if (NULL != p)printf(“ S' , p);(2)内存空间释放后指针未置 Null ,内存指针仍被继续使用 void* g_pBuf = NULL;void ATM_CellRecv(U8 *pBuf,U32 ulLe n)g_pBuf =
12、 pBuf;/g_pBuf通过pBuf赋值指向内存区域if ( NULL != pBuf ) free(pBuf);/只是释放了内存,而g_pBuf并没有置成NULL.void func2()g_pBuf = pBuf;if (NULL != g_pBuf)/赋值操作,将导致非法内存改写3.2内存拷贝忽略字符串结尾标志0'错误:void fun()char dest10;char src = "0123456789"memcpy(dest, src, sizeof(src);正确:void fun()char src = "0123456789"
13、int iLe nght = sizeof(src);char* dest= new chariLe nght;memcpy(dest, src, iLe nght);delete pdest;字符串结束符相关有许多安全函数可供调用:sn pri ntf,strncpy,strncat,safecopy等等,不允许使用非安全函数:sprint, strcpy3.3分支流程未释放动态申请的内存void Function 1(i nt n Size)char* p= (char*)malloc (n Size);if( !GetStri ngFrom(p, nSize)MessageBox( “
14、Error ” );return;/using the stri ng poin ted by p;free(p);当函数GetStringFrom()返回零的时候,指针p指向的内存就不会被释放。这是一种常见的发生内存泄漏的情形。程序在入口处分配内存,在出口处释放内存,但是c函数可以在任何地方退出,所以一旦有某个岀口处没有释放应该释放的内存,就会发生内存泄漏。内存分配方式有三种:(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都 存在。例如全局变量,static变量,静态内存区。(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建
15、,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc申请任意多少的内存,程序员自 己负责在何时用free释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显式释放的内存。应用程序一般使用malloc,realloc等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free释放该内存块,否则,这块内存就不能被再次使用,
16、我们就说这块内存泄漏了。3.4数据类型不一致,变量或参数赋值出错short int x; int y;void *p ; p=&x;*(i nt*)p=y;x只有两个字节的空间,而int需要4个字节的空间,实际上己出问题,编译器未设定字节对齐时会出错,在linux下不会出现入参被踩。还有一个例子,会导致入参被踩:int fun c(short int s, int* pi)/do someth ing*pi = 0; return 0;int main (i nt argc, char* argv)short int x;short int y;int iRet;/do someth
17、ingx = 1;iRet = func(x, (int *)& y);调用函数func后,x = 0 。3.5循环体内改写循环变量un sig ned long i;for (i = 0; i < 1024; c+)for (i = 0; i < 512;c+)尽量避免在循环中修改循环变量/do somethi ng3.6魔鬼数字如:0x01,“,“”,“ B-DISP ” ;错误:if ("B-DISP" = attributeListi.attributeType)正确:将字符串 "B-DISP" 在*.h文件中定位为字符串常量
18、ECC_LDAPATTRS_B-DISPconst TStri ng ECC_LDAPATTRS_B-DISP ="B-DISP"if (ECC_LDAPATTRS_B-DISP = attributeListi.attributeType)3.7对只读参数未加const修饰错误:void Fun c(char *src, char *dst, int len)strncpy(src,dst, len);/误操作将 src 的值改写正确:void Func( const char *src, char *dst, i nt len)strn cpy(dst, src, le
19、 n);3.8各种资源句柄没有释放FILE *fp1 = fopen( “file ” , w+);Retur n 0;首次打开文件,使用后未关闭文件句柄,执行不成功。正确:FILE *fp2 = fopen( “file ” , a+);if (NULL != fp2)fclose(fp2);Return 0;ElseReturn -1;CStri ng 中 GetBuffer 和 ReleaseBuffer的使用;信号量、临界区和互斥锁等同步对象资源;线程进程资源;3.9变量名、枚举名、常量名字面意思、注释含义与使用时相反CVACSubScirbeReq中字段:CMsgFieldI nt
20、m_isNeedNotifySP; /CRM侧订购的是否需要通知 SP该字段本意是个枚举值(ENUM),取值有2个:enum isNotifySPNotify_SP_NO = 1,/不通知Notify_SP_YES = 2 /通知 SP;/下面的逻辑是需要通知sp才处理的,枚举含义和实际意义完全颠倒if (From_CRM = pSessio nln fo->m_reql nfo.m_CRMOrderFlag.asl nt()&& Notify_SP_NO =pSessi onlnfo->m_reqlnfo. m_isNeedNotifySP.as In t()3.10所有的可能抛异常的地方都要有捕获spid,billm on th,amount,const char *sql = "select msisd n, serviceid, acco unt, rewardAm ount, rewardAcco un t,realacco unt fromhistoryrecordwhere msisdn = :v1 and serviceid = :v2 and spid = :v3&qu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 歌曲 在太行山上教学设计初中音乐粤教版八年级下册-粤教版
- 2026年青海省达日县藏医院自主招聘编外(临聘)人员7人笔试模拟试题及答案解析
- 业务合作诚信互惠承诺书范文4篇
- 2026重庆市铜梁区市场监督管理局食品药品监管公益性岗位招聘2人考试备考题库及答案解析
- 2026年招标代理和合同(1篇)
- 珠海发展演讲稿英文作文
- 红领巾飘起来 演讲稿
- 诗文咏万州的演讲稿
- 稳定供货价格控制承诺书范文3篇
- 2025-2026学年认知教案水果
- 赠从弟其二刘桢课件
- 党的二十届四中全会学习试题
- 肿瘤化疗脑患者注意力缺陷计算机化认知训练方案
- 委托验资合同范本
- 2026年陕西青年职业学院单招职业技能测试题库必考题
- 2025年西安中考历史试卷及答案
- VBSE实训总结与心得体会
- 车间5S知识培训课件
- 村级组织信访知识培训班课件
- 飞檐一角课件
- 财务岗位招聘笔试题及解答(某大型国企)2025年附答案
评论
0/150
提交评论