代码审查九句真言

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

看见了If,就想Else。

看见malloc,就去找Free。

函数调用要小心,需要看看返回值。

看到for循环,就找边界值。

看见return要注意,要去前面找资源。

看见数组把神提,问题往往在下标。

不要小看字符串,长度是个大问题。

得到函数不要急,看看变量初始化,各种路径要小心。

赋值函数最危险,变量没有初始化。

九句句真言不孤立,相互结合显神威。

真言详解

1.看见If,就想Else。

看到if语句,就要想到else语句。如果没有else语句,就要分析是不需要,还是异常情况没有处理,如果是异常情况没有处理,可以提单。

2.看见malloc,就去找Free。

看到malloc语句分配了内存,立即停下正常走读,看malloc代码之后,是否在所有程序的返回分支中都有释放语句。

典型案例:

U32 DEV_IfSetSectionEnable(DEV_IF_T *pIfIns)

{

CHAR * pSectionName = NULL;

ULONG ulMsg[4];

/* 向配置文件发送消息DEV_IF_READ_SECTION, 进行配置下载 */

pSectionName = VOS_Malloc(MOD_DEV, MAX_INTERFACE_NAME_LEN+1);

if ( pSectionName != NULL )

{

VOS_strcpy(pSectionName,pIfIns->ifName);

ulMsg[0] = MID_DEV;

ulMsg[1] = MID_CFM;

ulMsg[2] = DEV_CFM_ENABLE_SECTION;

ulMsg[3] = (ULONG)pSectionName;

VOS_Que_Write(ulVRPQID_CFM , ulMsg, VOS_NO_WAIT, 0);

return SUCCESS;

}

return DEV_ERR_NOMEMORY;

}

该函数有了VOS_Malloc,但没有看到free。于是在下面的代码中寻找,发现VOS_Que_Write中自动实现free功能。代码看似没有问题,但我们发现VOS_Que_Write的返回值没有判断,如果VOS_Que_Write返回失败,free语句就没有被执行到。这样可以确认该函数存在内存泄露隐患。该代码最终修改:U32 DEV_IfSetSectionEnable(DEV_IF_T *pIfIns)

{

CHAR * pSectionName = NULL;

ULONG ulMsg[4];

ULONG rc;

/* 向配置文件发送消息DEV_IF_READ_SECTION, 进行配置下载*/

if(pIfIns == NULL || (VOS_strlen( pIfIns->ifName) > (MAX_INTERFACE_NAME_LEN+1)))

{

return DEV_ERR_GEN;

}

pSectionName = VOS_Malloc(MOD_DEV, MAX_INTERFACE_NAME_LEN+1);

if ( pSectionName != NULL )

{

VOS_strcpy(pSectionName,pIfIns->ifName);

ulMsg[0] = MID_DEV;

ulMsg[1] = MID_CFM;

ulMsg[2] = DEV_CFM_ENABLE_SECTION;

ulMsg[3] = (ULONG)pSectionName;

rc = VOS_Que_Write(ulVRPQID_CFM , ulMsg, VOS_NO_WAIT, 0);

if(rc != SUCCESS)

{

rc = VOS_Free(pSectionName);

VOS_DBGASSERT(rc == VOS_OK);

return DEV_ERR_GEN;

}

return SUCCESS;

}

return DEV_ERR_NOMEMORY;

}

3.函数调用要小心,需要看看返回值。

看到函数调用,要养成习惯,进入函数内部瞄一眼。看看函数的正常值和异常值都是什么。看看返回值需不需要判断。看看有没有参数理解不一致的地方。例如:

if ( VOS_strnicmp(szFullName, DEV_ATM_NAME , DEV_ATM_NAMELEN) == 0 )

{

ulIfType = DEV_GetIfTypeFromIfName( szFullName );

if ( ulIfType == -1 )

{

EXEC_OutString( ulExecID, "\r\nUnknown interface type" );

return VOS_ERR;

}

/*得到端口的索引*/

ulRet = DEV_GetIfIndexFromIfName( szFullName, &ulIfIndex);

if (SUCCESS != ulRet)

{

EXEC_OutString( ulExecID, "\r\nUnknown interface number" );

return VOS_ERR;

}

/*判断端口是否已经存在*/

pIfIns = DEV_GetIfFromIndex(ulIfIndex);

if(NULL == pIfIns)

{

rc = DEV_Cnsl_CreateIf(ulExecID, ulIfType, ulIfIndex, ulSubType);

if(SUCCESS != rc)

{

return SUCCESS;

}

相关文档
最新文档