【发布时间】:2017-08-06 01:29:24
【问题描述】:
class Foo
{
public:
Foo(int i)
{
_i = i;
}
void p()
{
cout<<"printed"<<endl;
}
int _i;
};
int main()
{
Foo *p = 0;
cout <<p<<endl;
p->p();
return 0;
}
以上代码的实际输出为
0
printed
据我了解,访问 0x0 地址应该会导致 SEG 错误。 因为*p地址是0x0。
它为什么起作用?有人解释一下吗?
【问题讨论】:
-
这是Undefined Behaviour。任何事情都可能发生,直到并包括出现工作。在这种情况下,如果您真的想看到崩溃,请尝试在
Foo中添加一个成员变量,在Foo::p()中打印,以实际强制计算机尝试访问无效地址的一些内存。 -
取消引用空指针始终是未定义的行为。 然而,你“只是”调用一个成员函数,因此编译器实际上并没有取消引用指针,它只是跳转到一些代码。如果在函数内部使用
this(例如打印_i的值),情况就完全不同了。 -
因为事实上
*p没有在任何地方被取消引用。一个类的方法有一个包含this的隐藏参数,所以你的调用被翻译成methodp(pointerp);没有取消引用。请注意,如果methodp是virtual,那么您肯定会崩溃 -
当您调用未定义行为时,您的程序不受 C++ 语言的任何语义保证。
-
如果你真的想增加你的故障几率,添加
<< _i到你在p()的输出。无论如何,您正在调用未定义的行为。想想你自己不幸它没有在你预期的时候崩溃。
标签: c++