科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道野指针安全论

野指针安全论

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

野指针,也就是指向不可用内存区域的指针。通常对这种指针进行操作的话,将会使程序发生不可预知的错误。但是,我在文中要说的,就是野指针的“安全”使用方法以及其内部的原因。

作者:ghost 来源:CSDN 2007年9月24日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共2页)

关于成员函数CTestClass::Function的补充说明

这个函数是一个普通的成员函数,它在编译器的处理下,会成为类似如下的代码:

void Function( const CTestClass * this ) // ①
{
    printf("This is a test function.\n");
}

那么p->Function();一句将被编译器解释为:

Function( p );

这就是说,普通的成员函数必须经由一个对象来调用(经由this指针激活②)。那么由上例的delete之后,p指针将会指向一个无效的地址,然而p本身是一个有效的变量,因此编译能够通过。并且在编译通过之后,由于CTestClass::Function的函数体内并未对这个传入的this指针进行任何的操作,所以在这里,“野指针”便成了一个看似安全的东西。

然而若这样改写CTestClass::Function:

void CTestClass::Function( void )
{
    m_nInteger = 0;
}

那么它将会被编译器解释为:

void Function( const CTestClass * this )
{
    this->m_nInteger = 0;
}

你看到了,在p->Function();的时候,系统将会尝试在传入的这个无效地址中寻找m_nInteger成员并将其赋值为0,剩下的我不用说了——非法操作出现了。

至于virtual虚函数,如果在类定义之中将CTestClass声明为虚函数:

class CTestClass
{
public:
    // ...
    virtual void Function( void );
};

那么C++在构建CTestClass类的对象模型时,将会为之分配一个虚函数表vptr(可以从sizeof看出来)。vptr是一个指针,它指向一个函数指针的数组,数组中的成员即是在CTestClass中声明的所有虚函数。在调用虚函数的时候,必须经由这个vptr,这也就是为什么虚函数较之普通成员函数要消耗一些成本的缘故。以本例而言,p->Function();一句将被编译器解释为:

(*p->vptr[1])( p ); // 调用vptr表中索引号为1的函数(即Function)③

上面的代码已经说明了,如果p指向一个无效的地址,那么必然会有非法操作。

备注:

①关于函数的命名,我采用了原名而没有变化。事实上编译器为了避免函数重载造成的重名情况,会对函数的名字进行处理,使之成为独一无二的名称。
②将成员函数声明为static,可以使成员函数不经由this指针便可调用。
③vptr表中,索引号0为类的type_info。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1667477

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章