调试实战之临时对象

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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

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)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航