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)个字节的内存都被清零,虚指针被破坏,并指向了空,造成了函数执行错误。