C ++奇怪的行为

时间:2011-09-27 05:44:41

标签: c++

请检查此代码..

class ex
{
     int i;
     public:
     ex(int ii = 0):i(ii){}
      ~ex(){cout<<"dest"<<endl;}
     void show()
     {
        cout<<"show fun called"<<endl;
     }
};
int main(int argc , char *argv[])
{
    ex *ob = NULL;
     ob->show();
       return 0;
}

当我们调用show方法时会发生什么。

谢谢..

4 个答案:

答案 0 :(得分:3)

ex *ob = NULL;
ob->show();

您正在取消引用导致未定义行为的空指针。这很糟糕。

如果不清楚取消引用的位置,则了解->运算符转换为 (*ob).show()

答案 1 :(得分:3)

这是未定义的行为。

话虽如此,在大多数编译器中,只要

,您就可以调用空指针上的方法。

1)他们不会访问会员。

2)它们不是虚拟的。

大多数编译器都会翻译

ob->show()

call ob::show

这是应用程序空间中存在的有效方法。由于您没有访问成员,因此没有理由发生崩溃。

答案 2 :(得分:1)

在空指针指向的对象上调用show方法被归类为“未定义的行为”,这意味着无论发生什么,你都无法判断C ++是错误的,因为你身边的错误。

未定义的行为意味着编译器编写者不需要关心编程错误的后果......所以他们可以自由地忽略这些情况。通常,未定义的行为被认为意味着“崩溃”,但这与事实相去甚远。执行具有未定义行为的代码可能崩溃,可能无所事事,可能显然什么都不做,让您的程序稍后在一个非常好的地方崩溃一百万条指令,甚至可能正在运行显然很好,没有崩溃,但默默地破坏你的数据。

C ++语言的一个主要假设是程序员不会搞错。在其他语言中,这不是真的,你会得到“运行时错误天使”,当你犯错误时会检查并停止你的程序......在C ++中,这些检查被认为太昂贵,因此你得到的不是“运行时错误天使” “未定义的行为守护进程”,如果出现错误,您将获得乐趣。

这增加了C ++的高度复杂性,我认为C ++对于初学者来说是一个非常糟糕的选择(初学者会犯很多错误),并且无法通过实验来学习C ++(因为错误的后果)是非确定性的。)

在你的特定情况下,鉴于编译器编写者是懒惰的(程序员的质量不是很差),我猜想在x86架构上代码不会造成任何损害,它可能会像指针一样执行到一个有效的对象。 这当然只是推测,因为它取决于编译器,硬件和编译器选项。可能有好的编译器有一个编译调试选项,会生成代码崩溃的代码。

答案 3 :(得分:0)

行为未定义。程序实际上的行为方式依赖于实现。我希望大多数实现尝试执行代码而不检查指针。所以你的初始例子应该顺利运行,因为它没有引用该类的任何本地成员。

检查以下代码的作用很有趣:

class ex
{
    int i;
    public:
    ex(int ii = 0):i(ii){}
    ~ex(){cout<<"dest"<<endl;}
    virtual void show()
    {
        cout<<"show fun called"<<endl;
    }
};

int main(int argc , char *argv[])
{
    ex *ob = NULL;
    ob->show();
    return 0;
}

如果方法是虚拟的,则运行时可能需要访问对象的某些本地数据,从而导致空指针或错误的地址异常。

修改

我在cygwin上使用GCC测试了以下略微修改的示例:

#include <iostream>

using namespace std;

class ex
{
    int i;
    public:
    ex(int ii = 0):i(ii){}
    ~ex(){cout<<"dest"<<endl;}

    void show()
    {
        cout<<"show fun called"<<endl;
    }

    virtual void vshow()
    {
        cout<<"vshow fun called"<<endl;
    }
};

int main(int argc , char *argv[])
{
    ex *ob = NULL;
    ob->show();
    ob->vshow();
    return 0;
}
事实上,输出是:

show fun called
Segmentation fault (Core dumped)