陈浩 C++ 对象的内存布局(下)勘误
来源:互联网 发布:佳能 35 1.4 知乎 编辑:程序博客网 时间:2024/06/17 22:13
不知道大家有没有看过 陈浩的C++ 对象的内存布局(下),作者给的代码并不能运行
作者文章 :http://blog.csdn.net/haoel/article/details/3081328
我改过的代码如下 重点是这句
#include "stdafx.h"#include <iostream>#include <string>#include <vector>#include <list>using namespace std;class B{public:int ib;char cb;public:B():ib(0),cb('B') {}virtual void f() { cout << "B::f()" << endl;}virtual void Bf() { cout << "B::Bf()" << endl;}};class B1 : virtual public B{public:int ib1;char cb1;public:B1():ib1(11),cb1('1') {}virtual void f() { cout << "B1::f()" << endl;}virtual void f1() { cout << "B1::f1()" << endl;}virtual void Bf1() { cout << "B1::Bf1()" << endl;}};class B2: virtual public B{public:int ib2;char cb2;public:B2():ib2(12),cb2('2') {}virtual void f() { cout << "B2::f()" << endl;}virtual void f2() { cout << "B2::f2()" << endl;}virtual void Bf2() { cout << "B2::Bf2()" << endl;}};class D : public B1, public B2{public:int id;char cd;public:D():id(100),cd('D') {}virtual void f() { cout << "D::f()" << endl;}virtual void f1() { cout << "D::f1()" << endl;}virtual void f2() { cout << "D::f2()" << endl;}virtual void Df() { cout << "D::Df()" << endl;}};void main(){D dd;typedef void(*Fun)(void);int** pVtab = NULL;Fun pFun = NULL;pVtab = (int**)ⅆcout << "[0] D::B1::_vptr->" << endl;pFun = (Fun)pVtab[0][0];cout << " [0] "; pFun(); //D::f1();pFun = (Fun)pVtab[0][1];cout << " [1] "; pFun(); //B1::Bf1();pFun = (Fun)pVtab[0][2];cout << " [2] "; pFun(); //D::Df();pFun = (Fun)pVtab[0][3];cout << " [3] ";cout << pFun << endl;//cout << pVtab[4][2] << endl;cout << "[1] = 0x";cout << (int*)((&dd)+1) <<endl; //????cout << "[2] B1::ib1 = ";cout << *((int*)(&dd)+2) <<endl; //B1::ib1cout << "[3] B1::cb1 = ";cout << (char)*((int*)(&dd)+3) << endl; //B1::cb1//---------------------cout << "[4] D::B2::_vptr->" << endl;pFun = (Fun)pVtab[4][0];cout << " [0] "; pFun(); //D::f2();pFun = (Fun)pVtab[4][1];cout << " [1] "; pFun(); //B2::Bf2();pFun = (Fun)pVtab[4][2];cout << " [2] ";cout << pFun << endl;cout << "[5] = 0x";cout << *((int*)(&dd)+5) << endl; // ???cout << "[6] B2::ib2 = ";cout << (int)*((int*)(&dd)+6) <<endl; //B2::ib2cout << "[7] B2::cb2 = ";cout << (char)*((int*)(&dd)+7) << endl; //B2::cb2cout << "[8] D::id = ";cout << *((int*)(&dd)+8) << endl; //D::idcout << "[9] D::cd = ";cout << (char)*((int*)(&dd)+9) << endl;//D::cdcout << "[10] = 0x";cout << (int*)*((int*)(&dd)+10) << endl;//---------------------cout << "[11] D::B::_vptr->" << endl;pFun = (Fun)pVtab[11][0];int temp = 0;__asm{mov temp, ecx //保存原始的ecx}//原始例子中注释掉 cout << " [0] ";这句就行,不注释的话也可以这样做cout << " [0] "; //pFun(); //D::f();//pFun();__asm{mov ecx, temp //还原过来}pFun(); //这样就可以直接调用了__asm{call pFun //继续汇编调用方法 简单直接call}//不用还原ecx 都可以直接调用 ,大家可以把上面的保护ecx操作注释掉试试__asm{mov edx, pFun;mov eax, [edx]shr eax, 8 //调整偏移add eax, 5 add edx, eax;add edx, 3 //由于thunk 就是那个vdisp什么的,必须跳过 sub ecx, [ecx-4]这句call edx }pFun = (Fun)pVtab[11][1];cout << " [1] "; pFun(); //B::Bf();pFun = (Fun)pVtab[11][2];cout << " [2] ";cout << pFun << endl;cout << "[12] B::ib = ";cout << *((int*)(&dd)+12) << endl; //B::ibcout << "[13] B::cb = ";cout << (char)*((int*)(&dd)+13) <<endl;//B::cb}
运行结果如图
之所以要调过那个ecx-4是因为图形
估计这篇文章没人看 屌丝文章,就算了,不解释了 无非是调过这句 sub ecx,dword ptr[ecx-4] ,如果加了cout << "[0]"什么的 改了ecx,导致取ecx-4异常违规而已
- 陈浩 C++ 对象的内存布局(下)勘误
- C++对象的内存布局(下)
- C++对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)(转)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(下)
- Nebula level03
- Struts2配置文件讲解
- Java反射机制(得到类的所有方法)
- 设计模式之单例模式
- android 开发环境搭建
- 陈浩 C++ 对象的内存布局(下)勘误
- 编程之美2013年大赛解题思路--初赛(A)
- 再谈Mat,详解
- android view的xml属性
- 第一章 离散时间信号和系统
- 编程之美2013年大赛解题思路--初赛(B)
- OpenCV训练分类器
- 删除某壁纸
- [应用代码] 高仿人人Android梦想版终极源码发送