Code Bye

this指针与虚指针的关系

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++反汇编与逆向分析技术揭秘》

5

哦,你是把指针指向的去对象清零啊
对于,没有虚函数(因而没有虚函数表指针的)类的对象,
这招是不管用的
假如对象有虚函数表指针,那么指针也被你清零了,
自然就找不到虚函数表了
也就是说,这个对象不完整了(该有的虚函数表丢失了)。
他自然也就不好调用虚函数了(内部的虚函数表地址为0,0地址这地方,并没有存放虚函数表)
这已经不是虚函数调用不了了
这会出错,程序崩溃。

15

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


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明this指针与虚指针的关系