对象不使用默认析构函数

class Test
{
public:
char cNum1;
int iNum2;
int* pInt;
}; Test _ReturnObject()
{
Test stLocalObject;
stLocalObject.cNum1 = 0;
stLocalObject.iNum2 = 1; stLocalObject.pInt = new int;
*stLocalObject.pInt = 0x55;
return stLocalObject;
} int main(int argc, char* argv[])
{
Test stObject;
stObject = _ReturnObject(); return 0;
}

分析以上代码的反汇编代码,发现编译器并没有调用析构函数。其会将_ReturnObject()函数内的局部对象先保存到main函数的栈空间中(实际是在函数内部调用了拷贝构造函数,进行了对象的复制),返回值eax为其首地址,接着会将保存在此处的对象复制到另一处栈空间中,接着利用此栈空间对接收返回对象的实际对象赋值。



我们产生疑问!既然eax地址处和从eax复制的另一处栈地址处都保存着返回对象的数据,是否两处地址都可以认为是实际的对象。如果其是实际的对象那么其一定会再生命周期快结束时调用析构函数,因为这里编译器没有调用默认的析构函数所以我们无法判断,我们下面需要自己指定析构函数来分析。

对象使用析构函数

我们在上述代码的基础上加上自己的析构函数,此析构函数会将对象动态申请的内存释放掉。

~Test()
{
if(pInt != NULL)
delete pInt;
}

我们查看其对应的汇编代码,发现其在对象返回的过程中将对象保存到eax地址后,直接将eax地址对应的对象保存到stObject中,当然这两处的对象也会分别调用析构函数。此eax地址对应的对象被称为临时对象,临时对象的生命周期仅限当前语句,因此当执行完stObject = _ReturnObject();语句后临时对象就会调用析构函数。(我们可以看到在一开始其就会为临时对象在栈中申请内存空间,接着让临时对象的地址作为参数入栈从而在_ReturnObject函数内部对临时对象进行复制)



值得注意的是我们这里的代码是会报错的,因为返回对象在_ReturnObject函数结束时就会调用析构函数将int* pInt对应的内存给撤销了,当eax地址对应的临时对象在调用析构函数是就会报错。(因为我们没有定义拷贝构造函数,所以其在复制对象时使用默认的浅拷贝构造函数)要想避免这样的错误我们需要自己定义拷贝构造函数(深拷贝)。

临时对象

临时对象存在是为了可以使代码编写者像这样_ReturnObject().cNum1在返回对象后直接使用相关数据成员。

不使用临时对象

如果我们用此形式 Test stObject = _ReturnObject(); 直接调用返回对象的函数则会以定义的实际对象的地址为参数而不是以临时对象的地址为参数,从而不使用临时对象。

使用拷贝构造函数

Test(Test& Object)
{
cNum1 = Object.cNum1;
iNum2 = Object.iNum2;
pInt = Object.pInt; }

我们来给类加上我们的拷贝构造函数,我们发现在_ReturnObject函数结束前会利用调用拷贝构造函数实现将返回对象保存到临时对象下(对象的复制),从而实现“返回对象”。

浅拷贝和深拷贝

浅拷贝和深拷贝主要是针对C++类中存在指针型数据成员而言的。浅拷贝就是单纯的进行成员值的复制,而深拷贝是对指针型变量所指向的内存重新申请新的内存,并将内存中的数据复制过去。上面我们所给出的拷贝构造函数就是一个典型的浅拷贝(默认拷贝构造函数也是浅拷贝)。

c++逆向分析----返回对象的更多相关文章

  1. HQL查询——查询返回对象类型分析

    关于HQL查询,我们可以结合hibernate的API文档,重点围绕org.hibernate.Query接口,分析其方法,此接口的实例对象是通过通过session.对象的creatQuery(Str ...

  2. C++反汇编与逆向分析技术揭秘

    C++反汇编-继承和多重继承   学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 一.单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的 ...

  3. Android逆向分析(2) APK的打包与安装背后的故事

    前言 上一次我们反编译了手Q,并遇到了Apktool反编译直接crash的问题,虽然笔者很想在这次解决这个问题,但在解决途中,发现该保护依赖于很多知识,所以本次先插入一下,正所谓知其然知其所以然,授之 ...

  4. Android逆向分析(2) APK的打包与安装

    http://blog.zhaiyifan.cn/2016/02/13/android-reverse-2/ 2/18日增加对aidl和java编译的描述. 前言 上一次我们反编译了手Q,并遇到了Ap ...

  5. [Android Security] Smali和逆向分析

    copy : https://blog.csdn.net/u012573920/article/details/44034397 1.Smali简介 Smali是Dalvik的寄存器语言,它与Java ...

  6. RE-1 逆向分析基础

    逆向分析基础 0x01-0x0C 本笔记使用汇编指令为x86架构下汇编指令,ARM架构汇编指令不做介绍 0x01. 关于RE 逆向工程(Reverse Engineering RE) 逆向分析方法: ...

  7. 《C++反汇编与逆向分析技术揭秘》--认识启动函数,找到用户入口

    <C++反汇编与逆向分析>和<程序员的自我修养>都是以VC6的代码作为例子讲解的.这里是在vs2017下,CRT代码有些区别,但整体流程上都是初始化环境,设置参数,最后转到用户 ...

  8. 病毒木马查杀实战第012篇:QQ盗号木马之逆向分析

    前言 在本系列的文章中,对每一个病毒分析的最后一个部分,若无特殊情况,我都会采用逆向分析的手段来为读者彻底剖析目标病毒.但是之前的"熊猫烧香"病毒,我用了三篇文章的篇幅(每篇250 ...

  9. 【C++】从零开始的CS:GO逆向分析3——写出一个透视

    [C++]从零开始的CS:GO逆向分析3--写出一个透视 本篇内容包括: 1. 透视实现的方法介绍 2. 通过进程名获取进程id和进程句柄 3. 通过进程id获取进程中的模块信息(模块大小,模块地址, ...

随机推荐

  1. 20个最有用的Python数据科学库

    核心库与统计 1. NumPy(提交:17911,贡献者:641) 一般我们会将科学领域的库作为清单打头,NumPy 是该领域的主要软件库之一.它旨在处理大型的多维数组和矩阵,并提供了很多高级的数学函 ...

  2. CSS盒子的尺寸

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  3. java例题_33 等腰输出杨辉三角

    1 /*33 [程序 33 杨辉三角] 2 题目:打印出杨辉三角形(要求打印出 10 行如下图) 3 程序分析: 4 1 5 1 1 6 1 2 1 7 1 3 3 1 8 1 4 6 4 1 9 1 ...

  4. 第三单元总结——JML契约式编程

    OO第三单元博客作业--JML与契约式编程 OO第三单元的三次作业都是在课程组的JML规格下完成.完成作业的过程是契约式编程的过程:设计者完成规格设计,实现者按照规格具体实现.作业正确性的检查同样围绕 ...

  5. CodeForces571A. Lengthening Sticks(组合数学-容斥)

    题目大意: a,b,c三根木棍可以增加三个不同的数字,aa,bb,cc,且aa+bb+cc<=L,问能构成三角形的木棒有多少种方案 题目思路: 如果我们直接考虑把L分配给aa,bb,cc好像不好 ...

  6. Nginx日志分析 awk 命令

    通过Nginx日志,可以简单分析WEB网站的运行状态.数据报表.IP.UV(unique visitor指独立访客访问数,一台电脑终端为一个访客.).PV(page view即页面访问量,每打开一次页 ...

  7. PaddleOCR详解

    @ 目录 PaddleOCR简介 环境配置 PaddleOCR2.0的配置环境 Docker 数据集 文本检测 使用自己的数据集 文本识别 使用自己的数据集 字典 自定义字典 添加空格类别 文本角度分 ...

  8. 对不起,“下一代ERP”仍旧是现在的ERP

    最近数字化转型太火了,到处都是相关数字化的网文.很多人又说在数字化转型时代,ERP早就落伍了云云,取而代之的是什么"下一代ERP",叫什么"ARP"." ...

  9. Linux pgrep命令

    1 pgrep pgrep是一个根据名称查找进程ID的命令,返回的是进程ID,若存在当个进程,则分为不同的行返回ID(默认实现). 2 示例 查找java进程: pgrep java 上图还显示了ps ...

  10. Github仓库master分支到main分支迁移指南

    1 概述 2020年10月1日后,Github会将所有新建的仓库的默认分支从master修改为main,这就导致了一些旧仓库主分支是master,新仓库主分支是main的问题,这在有时候会带来一些麻烦 ...