Chinaunix首页 | 论坛 | 博客
  • 博客访问: 567189
  • 博文数量: 493
  • 博客积分: 2891
  • 博客等级: 少校
  • 技术积分: 4960
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 17:11
文章分类

全部博文(493)

文章存档

2010年(493)

分类:

2010-05-12 19:48:34

1 现象:问题描述
在Diameter项目组开发时,碰到了一个coredump的问题,经过gdb跟踪,发现是在执行下面的语句(斜体表示)时出现的coredump:
IDiamTransport* pConnector = NULL;
pConnector = m_pIDiamTransportManager->create(ptTCPConnector,tPeerData.connId);
CDiamPeerEntity* pPeerEntity = NULL;
NEW(pPeerEntity,CDiamPeerEntity);
DInt4 nErr=pPeerEntity->initialize(tPeerData,pConnector,this,m_pLogger,pIDiamTimer,
m_pIDiamBaseStackInner,bServer); //peerEntity的初始化函数
if (DIAM_SUCCESS != nErr)
{
    DELETE(pPeerEntity);
    if (NULL != pConnector)
    {
        m_pIDiamTransportManager->destroy(pConnector); //出现coredump现象
pConnector = NULL;
    }
   
    WriteLog(HD(llFatal)," pPeerEntity->initialize() faild!");
    return DIAM_FAILED;
}
上面m_pIDiamTransportManager->destroy(pConnector)语句,在执行之前判断了pConnector是否为NULL,应该属于正常的内存释放,但这里出现了coredump现象,实在比较让人费解。
2 关键过程:根本原因分析
在跟踪pPeerEntity->initialize(tPeerData,pConnector,this,m_pLogger,pIDiamTimer,
m_pIDiamBaseStackInner,bServer)的函数实现时,发现了下面的语句:
m_pConnector = pConnector;
并且CDiamPeerEntity类的析构函数中有下面的语句:
if ((NULL != m_pPeerManager->getTransportManager()) && (NULL != m_pConnector))
{
    m_pPeerManager->getTransportManager()->destroy(m_pConnector);
    m_pConnector = NULL;
}
从上面的程序段可以看到,pConnector被赋值给CDiamPeerEntity的成员变量m_pConnector,并且在CDiamPeerEntity对象被析构时,将成员m_pConnector的内存释放了。这样,就使得pConnector指向的内存空间被释放了两次:
第一次:m_pPeerManager->getTransportManager()->destroy(m_pConnector);
第二次:m_pIDiamTransportManager->destroy(pConnector);
导致了coredump的产生。
3 结论:解决方案及效果
这个问题的解决方法是删除下面的语句:
m_pPeerManager->getTransportManager()->destroy(m_pConnector);
删除这条语句后,问题得到了解决。
4 经验总结:预防措施和规范建议
在动态内存的使用上,我们一方面防止申请的内存未释放,另一方面也要防止同一块内存被两次或多次释放。为了防止内存的申请或者释放出现错误,建议内存的申请和释放应该在同一个作用域内对称、成对地出现,作用域外不得释放作用域内申请的内存。
5 备注
无。
6 考核点
动态内存的申请和释放规则。
7 试题
对于动态内存申请和释放的代码实现,下面哪种方式不好:
(1)
void CTest::Func1()
{
//…其它代码
m_pVar = new CVar();
//…其它代码
}
void CTest::Func2)
{
//…其它代码
delete m_pVar;
m_pVar = NULL;
//…其它代码
}
(2)
void CTest::CTest()
{
//…其它代码
m_pVar = new CVar();
//…其它代码
}
void CTest::~CTest()
{
//…其它代码
delete m_pVar;
m_pVar = NULL;
//…其它代码
}
(3)
void CTest::Func ()
{
//…其它代码
m_pVar = new CVar();
//…其它代码
delete m_pVar;
m_pVar = NULL;
//…其它代码
}
答案:(1)
阅读(485) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~