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