一、沒有對全部入參指針作有效性檢查
WORD32 Test(WORD32 *p,
WORD32 *q
)
{
WORD32 dwBindType = 0;
if ((NULL == p) ||
(NULL == q)
)
{
SF_ASSERT(0);
return SFWD_ERROR;
}
return SFWD_OK;
}
編程規範要求,全部入參是指針,都必須進行判空操做;若是是入參是整型等,能夠根據須要決定是否對入參進行檢查;但參數不合法都要作異常處理;
二、函數中的異常處理缺乏返回值
WORD32 Test(WORD32 *p, WORD32 *q)
{
WORD32 dwBindType = 0;
if ((NULL == p) || (NULL == q))
{
SF_ASSERT(0);
return SFWD_ERROR; //致使與預期返回的結果不符
}
return SFWD_OK;
}
斷言須要作異常處理的,並非斷言就完事了,若是tr掉,繼續往下走,可能會出現跑飛或單板重啓等嚴重問題;
在release版本,斷言是被忽略的;debug版本,適當增長斷言,當出現異常時,容易定位問題。
三、函數在異常退出前務必要釋放先前申請的內存
SOCK_PKTINFO* Test(WORD32 dwReplyType)
{
BYTE *pValidatePkt = NULL;
SOCK_PKTINFO *pPktInfo = NULL;
pValidatePkt = (BYTE *)
XOS_GetUB
(VER_REPLY_PKTLEN);
if (NULL == pValidatePkt)
{
ROSNG_TRACE_ERROR("Error: XOS_GetUB failed!\n");
return NULL;
}
MEMSET(pValidatePkt, 0, VER_REPLY_PKTLEN);
if (TOPO_REPLY_OK == dwReplyType)
{
MEMCPY(&pValidatePkt[4], "YES", 4);
}
else
{
SF_ASSERT(0);
XOS_RetUB(pValidatePkt);
return NULL;
}
return pPktInfo;
}
這段代碼其實有幾個問題:
1.沒有遵照誰申請誰釋放的原則,C語言很容易出現內存泄漏,但遵照規範,這種泄漏就會少不少;
除了申請的內存須要緩存而不是在一個消息中釋放外(好比分片組包的狀況),報文處理中基本上能夠作到誰申請誰釋放;
2.在異常流程,沒有釋放內存,這個是很是容易犯的錯誤;
3.若是是臨時申請內存,應該使用PUB_GetLocalUB/PUB_RetLoacalUB這對接口;
四、函數內對空指針進行引用操做
VOID Test(SFWD_NBR_INFO *pNbrInfo)
{
WORD32 *
pIndex
= NULL;
if(NULL == pNbrInfo)
{
ROSNG_TRACE_ERROR("Error: Para is NULL!\n");
SF_ASSERT(0);
return;
}
if(0 == pNbrInfo->wActiveNbrNum)
{
pIndex
= sfwd_node_new(sizeof(WORD32));
if(NULL == pIndex)
{
ROSNG_TRACE_ERROR("Error: sfwd_node_new return NULL!\n");
return;
}
*
pIndex
= pVifInfo->dwIndex;
}
XOS_RawPrint("gIndex = %d, pNbrInfo->dwNbrStatus = %d\n", *
pIndex
, pNbrInfo->dwNbrStatus);
//這裏若是沒有執行上面if語句內的代碼,就會致使對空指針進行操做;
return;
}
無論是打印仍是語句,只有是訪問指針指向的內容,先想一想這個指針有沒有爲空或非法地址的狀況;
五、函數中數組操做的越界訪問
WORD32 Test(SFWD_TOPO_PKT_CAP_IF_INFO_T *pIfInfo, WORD32 gIndex)
{
WORD32 dwSubslot = 0;
WORD32 dwSubindex = 0;
WORD16 if_type = 0;
if (NULL == pIfInfo)
{
ROSNG_TRACE_ERROR("sfwd_topo_pkt_cap_get_ifinfo: inParam is NULL!\n");
SF_ASSERT(0);
return FALSE;
}
if ((gIndex <= 0))
{
ROSNG_TRACE_ERROR("sfwd_topo_pkt_cap_get_ifinfo: Para error!\n");
SF_ASSERT(0);
return FALSE;
}
dwSubslot
= gIndex / MAX_IF_NUMBER_PERCARD;
dwSubindex
= gIndex % MAX_IF_NUMBER_PERCARD;
if((dwSubslot >= MAX_SUBCARD_NUMBER) || (dwSubindex > MAX_IF_NUMBER_PERCARD))
{
ROSNG_TRACE_WARNING("sfwd_topo_pkt_cap_get_ifinfo: invalid subslot or subindex.\n");
SF_ASSERT(0);
return FALSE;
}
if_type = gInterface[dwSubslot][dwSubindex].wType;
//在對gInterface數組進行訪問時,若是dwSubslot、dwSubindex的下標值超出了該數組聲明的大小可能產生越界。因此,須要根據代碼的上下文來對數組的下標作有效性檢查(並非全部的數組訪問都檢查,有些是不必的)
return TRUE;
}
#define SFWD_SUBCARD_NO_CHECK(A, B) ((A >= MAX_SUBCARD_NUMBER) || (B > MAX_IF_NUMBER_PERCARD))
數組越界也是常常犯的錯誤,對數組的訪問,加一下檢查;考慮到會頻繁出現數組下標的檢查,能夠寫一個相似上面的宏;