this指针和虚指针或和虚表之间有什么关系呢?
引发问题的代码如下:
引发问题的代码如下:
class A { public : A() { //this->fun (); //这样后无法通过this指针调用虚函数,但可以调用普通函数。 memset(this,0,sizeof(*this)); } void virtual fun() { this->test (); cout<<"fun"<<endl; cout<<this<<endl; } void test () { cout<<"test"<<endl; //this->fun (); cout<<this<<endl; } }; void testA() { A a; a.fun (); //a.test (); /*A &aa=a; aa.fun ();*/ A *pa=&a; //pa->fun (); pa->test (); }
解决方案
5
《深度探索C++对象模型》
《C++反汇编与逆向分析技术揭秘》
《C++反汇编与逆向分析技术揭秘》
5
哦,你是把指针指向的去对象清零啊
对于,没有虚函数(因而没有虚函数表指针的)类的对象,
这招是不管用的
假如对象有虚函数表指针,那么指针也被你清零了,
自然就找不到虚函数表了
也就是说,这个对象不完整了(该有的虚函数表丢失了)。
他自然也就不好调用虚函数了(内部的虚函数表地址为0,0地址这地方,并没有存放虚函数表)
这已经不是虚函数调用不了了
这会出错,程序崩溃。
对于,没有虚函数(因而没有虚函数表指针的)类的对象,
这招是不管用的
假如对象有虚函数表指针,那么指针也被你清零了,
自然就找不到虚函数表了
也就是说,这个对象不完整了(该有的虚函数表丢失了)。
他自然也就不好调用虚函数了(内部的虚函数表地址为0,0地址这地方,并没有存放虚函数表)
这已经不是虚函数调用不了了
这会出错,程序崩溃。
15
base drived
pvtal–> vtable–>fun1 fun1
fun2 fun2
对象内部,只是存储一个指针
这个指针指向一个表
VC的某个版本,这是个 数组
这个数组 包含基类的 虚函数表(指针),派生类本人的虚函数表(指针),等若干个表
虚函数调用,就是查表,根据函数的位置找到虚函数的函数指针。调用函数
pvtal–> vtable–>fun1 fun1
fun2 fun2
对象内部,只是存储一个指针
这个指针指向一个表
VC的某个版本,这是个 数组
这个数组 包含基类的 虚函数表(指针),派生类本人的虚函数表(指针),等若干个表
虚函数调用,就是查表,根据函数的位置找到虚函数的函数指针。调用函数
15
可以通过反汇编和内存调试窗口来分析这个问题,本人对你的代码做了一点改动,在A类里添加了一个成员变量m_i,具体如下:
class A { public : int m_i; A() { m_i=4294967295;//FFFFFFF memset(this,0,sizeof(*this)); } void virtual fun() { this->test (); cout<<"fun"<<endl; cout<<this<<endl; } void test () { cout<<"test"<<endl; //this->fun (); cout<<this<<endl; } }; void testA() { A a; a.fun (); //a.test (); /*A &aa=a; aa.fun ();*/ A *pa=&a; //pa->fun (); pa->test (); }
为了方便展示A对象的内存构造,将m_i赋值4294967295,原因是4294967295对应16进制0XFFFFFFFF。
Debug程序,进入反汇编界面,具体如下:
this指向0x0048f9f0,这是A对象的地址,最开始的四个字节就是虚指针,指向0x0034dc78(这个就是虚表),通过内存窗口,我们可以看看0x0034dc78(虚表)里存了些什么东西,具体如下:
可以看出0x0034dc78里面存放了一个代码段地址(0x00341055),通过反汇编找到这个地址,这个地址里存放代码的作用就是跳转到A:fun
当执行memset()函数时,0x0048f9f0开始后sizeof(*this)个字节的内存都被清零,虚指针被破坏,并指向了空,造成了函数执行错误。