调试实战之临时对象

类别:编程语言 点击:0 评论:0 推荐:

      临时对象,不知道什么时候编程就会碰到这个神秘的暗礁!我们来看下面这段代码:

 string s1, s2;
 s1 = "abc";
 s2 = "def";
  
 const char* cs = (s1 + s2).c_str();(1)
      你会想当然的认为,cs 会等于 "abcdef".然而,在
vc中调试状态运行,当你把鼠标放在cs上时,你会发现它是一片空白!!!这就是临时对象在搞鬼!
      s1+s2的结果会放在一个临时对象里,这个临时对象会在执行(1)时,将它内部存放"abcdef"的指针传给cs,而传给cs后它又会析构掉自己,删除自己内部存放字符串的指针.直接造成cs指向了一个无效地址!
    看看(1)的反汇编我们会清楚地发现这一过程!
0040519D   lea         edx,[ebp-30h]     //ebp-30h是s2的地址
004051A0   push        edx
004051A1   lea         eax,[ebp-20h]     //ebp-20h是s1的地址
004051A4   push        eax
004051A5   lea         ecx,[ebp-74h]     //ebp-74h就是临时对象的地址
004051A8   push        ecx                  //ecx指向代表临时对象string 类
004051A9   call        std::operator+ (004013e4)    // 临时对象 = s1+s2
004051AE   add         esp,0Ch
004051B1   mov         dword ptr [ebp-88h],eax
004051B7   mov         edx,dword ptr [ebp-88h]
004051BD   mov         dword ptr [ebp-8Ch],edx
004051C3   mov         byte ptr [ebp-4],2
004051C7   mov         esi,esp
004051C9   mov         ecx,dword ptr [ebp-8Ch]   //ebp-8ch也是临时对象的地址
004051CF   call        dword ptr [__imp_?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE //执行(s1+s2).c_str()
004051D5   cmp         esi,esp
004051D7   call        _chkesp (00404c0a)
004051DC   mov         dword ptr [ebp-34h],eax  //ebp-34是cs的地址 执行cs=临时对象字符串指针
004051DF   mov         byte ptr [ebp-4],1
004051E3   mov         esi,esp
004051E5   lea         ecx,[ebp-74h]
004051E8   call        dword ptr [__imp_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ //这句很关键,它调用了临时对象的析构函数,销毁自己,执行完这一步,cs也随之完蛋!

004051EE   cmp         esi,esp
004051F0   call        _chkesp (00404c0a)

 

本文地址:http://com.8s8s.com/it/it27430.htm