1 现象:问题描述
在对xxx产品进行单元测试时,发现程序core,并且异常退出。
2 关键过程:根本原因分析
通过使用gdb来跟踪core文件,发现是下面的代码导致程序退出:
TString strContact = DUMMY_STRING;
if ( NULL != pResp_c )
{
strContact = pResp_c->getContact()->getURI()->toString();
}
说明:
pResp_c为SipResponse*类型;
SipResponse::getContact()函数返回Address*类型;
Address::getURI()函数返回URI*类型;
URI::toString()函数返回TString类型;
经过分析,发现SipResponse::getContact()函数有可能返回NULL值,对NULL值调用成员函数,肯定会出现core的现象了。
3 结论:解决方案及效果
将上面的代码改写为:
TString strContact = DUMMY_STRING;
if ((pResp_c != NULL)
&& (pResp_c->getContact()!=NULL)
&& (pResp_c->getContact()->getURI()!=NULL))
{
strContact = pResp_c->getContact()->getURI()->toString();
}
4 经验总结:预防措施和规范建议
对于表达式组:
Address* pAddress = pResp_c->getContact();
URI* pUri = pAddress->getURI();
strContact = pUri->toString();
我们在真正实现时,会很习惯地写成如下的安全形式:
if (pResp_c!= NULL)
{
Address* pAddress = pResp_c->getContact();
if (pAddress!= NULL)
{
URI* pUri = pAddress->getURI();
if (pUri != NULL)
{
strContact = pUri->toString();
}
}
}
但对于表达式:
strContact = pResp_c->getContact()->getURI()->toString();
我们在实现时则很容易只进行一次判断:
if (pResp_c != NULL)
{
strContact = pResp_c->getContact()->getURI()->toString();
}
这样就忽略了pResp_c->getContact()和pResp_c->getContact()->getURI()的判断。正确的写法应该是:
if (pResp_c != NULL
&& pResp_c->getContact()!=NULL
&& pResp_c->getContact()->getURI()!=NULL)
{
strContact = pResp_c->getContact()->getURI()->toString();
}
5 备注
6 考核点
链式指针表达式
7 试题
对于链式指针表达式strContact = pResp_c->getContact()->getURI()->toString(),下面哪种写法最安全:
(1)
if ((pResp_c != NULL)
&& (pResp_c->getContact()!=NULL)
&& (pResp_c->getContact()->getURI()!=NULL))
{
strContact = pResp_c->getContact()->getURI()->toString();
}
(2)
if (pResp_c != NULL
&& pResp_c->getContact()!=NULL )
{
strContact = pResp_c->getContact()->getURI()->toString();
}
(3)
if (pResp_c != NULL )
{
strContact = pResp_c->getContact()->getURI()->toString();
}
(4)
strContact = pResp_c->getContact()->getURI()->toString();
答案:(1)
阅读(1054) | 评论(1) | 转发(0) |