调试实战之临时对象

原创 2004年09月15日 09:29:00

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

 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)

 

C++临时对象那些事儿

C++大概是这个世界上最飘逸、成功、失败的语言吧,临时对象是C++语言中最复杂的东西之一。 以下代码段新手大概经常会写吧: std::string FetchFormat(){ return "%d...
  • wind_2008_06_29
  • wind_2008_06_29
  • 2016年04月13日 16:55
  • 1365

C++中临时对象的产生与优化

C++中临时对象的产生与优化 本文主要介绍c++中临时对象产生的几种情况,同时介绍避免的策略。由于在C++中对象的创建和消除会调用该对象对应的构造和析构函数,是一个相对比较耗时的操作,从程序效率角度来...
  • fangqingan_java
  • fangqingan_java
  • 2013年07月13日 20:55
  • 1180

函数的返回值和临时对象的问题

在函数的声明时,其实是最重要的一步,如何设计一个好的接口(用户友好),直接决定了后面的编码工作是否能够行云流水。先给出整体架构,检查各类和接口之间的逻辑有没有问题。...
  • JiajieZhuo
  • JiajieZhuo
  • 2016年12月26日 20:52
  • 997

C++调用函数是如何返回临时对象的

请看如下代码 #include "stdafx.h" #include using namespace std; class INT { friend ostream& operator...
  • u012332679
  • u012332679
  • 2017年03月07日 18:03
  • 374

C++中函数返回临时对象和本地对象的区别

C++中函数返回临时对象和本地对象的区别                        By qianghaohao(CodeNutter)        在C++中如果函数返回值是对象的时候,那么该...
  • qianghaohao
  • qianghaohao
  • 2016年09月09日 20:48
  • 1527

C++临时对象销毁时间

下面这段代码会输出什么?
  • passion_wu128
  • passion_wu128
  • 2014年08月31日 12:29
  • 1782

C++中临时对象及返回值优化

一、什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象. 通常出现在以下两种情况:1 、为了使函数调用成功而进行隐式类型转换的时候...
  • yockie
  • yockie
  • 2016年07月10日 22:22
  • 630

C++学习笔记之——局部对象和临时对象的构造和析构时机

在写这篇文章之前,一直没有注意过C++中临时对象何时调用析构的。直到最近看代码的过程中遇到这种情况。 由于不了解临时对象何时调用析构函数,所以很不了解代码的实现。甚至还用局部对象的析构时机去看待。先讲...
  • huangjh2017
  • huangjh2017
  • 2017年04月19日 17:22
  • 385

C++11移动语义探讨——从临时对象到右值引用

一.前言这篇文章主要谈谈c++11中引入的右值引用概念和移动语义概念。以及这些东西可能在我们编程中带来哪些体验、便捷或者是代码效率的提高。 文章主要分为以下三点: 临时对象的产生 何谓右值引用 何谓...
  • y1196645376
  • y1196645376
  • 2017年02月07日 16:16
  • 637

C++中临时对象的产生

//《More Effective C++》读书笔记 C++真正的所谓临时对象使不可见的----不会在你的源代码中出现。 (不要把代码中出现的局部对象误解为临时对象) 临时对象通常发生于两种情...
  • sichuanpb
  • sichuanpb
  • 2017年04月13日 10:01
  • 119
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:调试实战之临时对象
举报原因:
原因补充:

(最多只允许输入30个字)