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

全部博文(493)

文章存档

2010年(493)

分类:

2010-05-12 18:41:26

const SString  CSrvSession::GetXMmsMessageID()
{
    return(SString(m_szXMmsMessageID));
};
请注意,GetXMmsMessageID()函数返回的是SString的值,而根据C++标准,函数返回一个右值需要创建一个临时变量!因此,编译器处理上面蓝色部分的语句时,需要使用一个临时的SString变量,将函数返回的值拷贝到这个临时变量里,然后取这个临时变量的一个内部指针赋值给pMessageID。这还不是问题的全部,同样根据C++标准,当引入临时变量的表达式整体计算完毕后,需要销毁该临时变量,即,如果该变量有一个"non-trivial"的析构函数,则需要对该临时变量执行其析构函数。显然,SString的析构函数是"non-trivial"的,因此,pMessage的赋值语句结束后,编译器会自动对上面引入的临时变量调用SString的析构函数,释放这段临时变量指向的内存!于是,pMessage就指向了一段已经被释放的内存,其内容当然很有可能是乱码了。C++标准中关于临时变量的描述请参考附录。
为了证实上面的猜想,用gdb跟踪一下程序:
Breakpoint 1, CSrvSvcLogProc::EnterMM1SubmitReqSvclog (pMM1SubmitReq=0x85ad408, )
    at /home/syb/mms_home/source/csrc/server/comm/srvsvclogproc.cpp:890
890         const char * pMessageID = rSrvSessWrapper->GetXMmsMessageID().c_str();
(gdb) s
CRecordWrapper::operator-> (this=0x45019920) at store_recordwrapper.cpp:833
833         return m_pRecord;
(gdb) s
CSrvSession::GetXMmsMessageID (this=0x4c1d645c) at /home/syb/mms_home/source/csrc/server/ srvsession.cpp:915
915         return(SString(m_szXMmsMessageID));
(gdb) s
allocator (this=0x45019690) at _alloc.h:345
345       allocator() _STLP_NOTHROW {}
(gdb) n
CSrvSession::GetXMmsMessageID (this=0x4c1d645c) at /home/syb/mms_home/source/csrc/server/srvsession.cpp:917
917     };
(gdb) s
_STL::basic_string, _STL::allocator >::c_str (this=0x45019770) at _string.h:1065
1065      const _CharT* c_str() const { return this->_M_start; }
(gdb) p this->_M_start
$1 = 0x4e6770b0 "032316440000495511010"
(gdb) s
~basic_string (this=0x45019770) at _string.h:305
305       ~basic_string() { _STLP_STD::_Destroy(this->_M_start, this->_M_finish + 1); }
(gdb) n
CSrvSvcLogProc::EnterMM1SubmitReqSvclog (pMM1SubmitReq=0x85ad408, )
    at /home/syb/mms_home/source/csrc/server/comm/srvsvclogproc.cpp:891
891         const char * pTranscationID = pMM1SubmitReq->GetstrXMmsTransactionID().c_str();
(gdb) p pMessageID
$2 = 0x4e6770b0 "鳾gN16440000495511010"
(gdb) c
Continuing.
从红色部分可以很明显的看到std::string的析构函数被执行了。对比在执行该函数前后的蓝色部分,可以看到同一个地址所代表的内容已经不一样了!
3 结论:解决方案及效果
既然问题是由临时变量引入的,那么,只要注意消除临时变量的影响就可以了。解决的方法很多,这里列举三种:
阅读(252) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~