陈浩 C++ 对象的内存布局(下)勘误
2013-05-10 14:39
267 查看
不知道大家有没有看过 陈浩的C++ 对象的内存布局(下),作者给的代码并不能运行
作者文章 :/article/2551888.html
我改过的代码如下 重点是这句
运行结果如图
之所以要调过那个ecx-4是因为图形
估计这篇文章没人看 屌丝文章,就算了,不解释了 无非是调过这句 sub ecx,dword ptr[ecx-4] ,如果加了cout << "[0]"什么的 改了ecx,导致取ecx-4异常违规而已
作者文章 :/article/2551888.html
我改过的代码如下 重点是这句
#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::ib1 cout << "[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::ib2 cout << "[7] B2::cb2 = "; cout << (char)*((int*)(&dd)+7) << endl; //B2::cb2 cout << "[8] D::id = "; cout << *((int*)(&dd)+8) << endl; //D::id cout << "[9] D::cd = "; cout << (char)*((int*)(&dd)+9) << endl;//D::cd cout << "[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::ib cout << "[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++对象模型之内存布局(2)
- C++ 对象的内存布局(下)
- C++对象内存布局--②测试派生类跟基类的虚函数表
- C++ 对象的内存布局(上)
- C++ 对象的内存布局(下)
- C++ 对象的内存布局(上)
- C++对象内存布局测试总结
- C++ 对象的内存布局
- c++ 对象的内存布局
- C++ 对象的内存布局(上)
- C++ 对象的内存布局(上)
- C++ 对象的内存布局(上)
- C++中派生类对象的内存布局
- C++ 对象的内存布局(下) .
- C++对象模型之详述C++对象的内存布局
- C++对象内存布局-单一继承
- C++ 对象内存布局 (2)
- C++ 对象内存布局 (下)