|
ail of C041 is f0 c2 45 00 01 The size of C140 is 14 The detail of C140 is 48 c3 45 00 02 00 00 00 00 44 c3 45 00 01 The size of C141 is 14 The detail of C141 is 58 c3 45 00 03 00 00 00 00 54 c3 45 00 01 The size of C150 is 20 The detail of C150 is 74 c3 45 00 02 68 c3 45 00 03 04 00 00 00 00 64 c3 45 00 01 和前面的布局不同之处在于,共享部分和前面的非共享部分之间多了4字节的0值。只有共享部分有虚表指针,这是因为派生类都没有定义自己的虚函数,只是重写了顶层类的虚函数。我们分析一下C150的对象布局。
|C140,5 |C141,5 |C150,1 |zero,4 |C041,5 | |ospt,4,15 |m,1 |ospt,4,10 |m,1 |m,1 |4 |vtpt,4 |m1 | (注:为了不折行,我用了缩写。ospt代表偏移值指针、m代表成员变量、vtpt代表虚表指针。第一个数字是该区域的大小,即字节数。只有偏移值指针有第二个数字,第二个数字就是偏移值指针指向的偏移值的大小。)
再看函数的调用:
C150 obj; PRINT_OBJ_ADR(obj) obj.foo(); 输出的对象地址为:
obj's address is : 0012F624 最后一行函数调用的代码对应的汇编代码为:
00423F74 lea ecx,[ebp FFFFF757h] 00423F7A call 0041DCA3 单步执行后,我们可以看到ecx中的值为:0x0012F633,这个地址也就是obj对象布局中的祖父类部分的起始地址。通过上面的布局分析我们知道 C150起始的偏移值指针指向的值为15,即对象起始到共享部分(祖父类部分)的偏移值。上面输出的obj起始地址为0x0012F624加上十进制的 15后,正好是我们看到的ecx中的值0x0012f633。
上一页 [1] [2]
|