当我调用NULL对象指针的成员函数时会发生什么?

我作为一个采访问题被给予以下:

class A { public: void fun() { std::cout << "fun" << std::endl; } }; A* a = NULL; a->fun(); 

这段代码执行后会发生什么,为什么?


也可以看看:

  • 什么时候调用null实例的成员函数会导致未定义的行为?

这是未定义的行为,所以可能发生任何事情。

一个可能的结果是,它只是打印"fun"因为该方法不访问它被调用的对象的任何成员variables(对象据认为居住的内存不需要被访问,所以访问冲突“一定会发生)。

按照标准,这是不确定的行为,因此是一件非常糟糕的事情。 在大多数编程平台(跨X86和其他几种架构)的实际情况下,这样可以很好地运行。

为什么? 考虑如何在C ++中实现类的function。 这不是一个虚拟函数,因此这可以是对已知地址的静态调用。 在x86汇编中,我们可以看到这个

 mov A, 0 mov ecx, A call a__fun 

因为a__fun不需要实例数据,即使它接收到null指针,也不会发生任何事情。

仍然低劣的代码和任何编译器会尖叫,但它可以运行。

在大多数现代计算机上,最可能的行为是运行,并打印出“有趣的”,因为:

  • 在调用函数之前,C ++不检查指针是否为NULL
  • fun()不是虚拟的,所以不需要引用一个vtable来调用fun()
  • fun()永远不会访问A任何成员variables,所以它不需要将this指针的空值解引用。

我们不知道会发生什么。 一切都可能发生,因为程序暴露了未定义的行为。 请参阅在空实例上调用成员函数是否导致未定义的行为? 。

我多次尝试过,一直输出“快乐”,这是因为函数fun独立于实例a 。 同时调用a->fun(); 指向0,所以这是未定义的行为,但在大多数编译器应该没有崩溃。