嗨,有人可以告诉为什么在Linux和Windows中出现同样的问题:
#include <iostream>
using namespace std;
class A
{
private:
int _dmember;
public:
void func()
{
cout<<"Inside A!! "<<endl;
cout<<_dmember; // crash when reach here.
}
};
int main ()
{
A* a= NULL;
a->func(); // prints "Inside A!!!"
return 1;
}
Run Code Online (Sandbox Code Playgroud)
有人能说出为什么会发生这种奇怪的事情吗?我的意思是,a-> func()不应该进入func(),...?这是不了解的行为,
为什么上面的behivor会发生?
编辑:当然,*= null是故意的!! 所以对于所有回答"这是未定义的行为"或"你永远不应该尝试在NULL指针上调用函数!!"的人来说,来吧....这就是重点.有些人正确解释了这种行为.
Tho*_*mas 12
这是未定义的行为.您绝不能在空指针上调用函数.
有了这个,让我们回答一下我认为你问的问题:为什么我们还要进入函数的中途?
当您调用UB时,编译器可以自由地执行任何操作,因此允许它发出仍然有效的代码.这就是在这种特殊情况下在某些(很多?)系统上发生的情况.
您能够成功调用空指针上的函数的原因是您的编译器不会将函数存储在对象中.相反,上面的代码有点像这样解释:
class A {
int _dmember;
};
void A::func(A *this) {
cout << "Inside A!!" << endl;
cout << this->_dmember << endl;
}
int main() {
A *a = ...;
A::func(a);
}
Run Code Online (Sandbox Code Playgroud)
所以,你看到没有任何东西可以阻止你在空指针上调用一个函数; 它只是调用函数体,this指针设置为null.但只要函数试图取消引用this通过访问类中的字段的指针,在操作系统的步骤,并杀死你的非法内存访问(在Linux上称为分段错误,访问冲突在Windows上)程序.
Nitpicker的角落:虚拟功能是另一回事.
未定义的行为,因为您正在访问NULL指针:
A* a= NULL;
a->func(); // is not defined by the language
Run Code Online (Sandbox Code Playgroud)
请注意,即使func()没有尝试访问成员变量,行为仍然是未定义的.例如,以下代码可以正常运行,但它不正确:
func()
{
cout<<"Inside A!! "<<endl;
}
Run Code Online (Sandbox Code Playgroud)
编辑:我充分尊重,C++不会太糟糕!
你需要的是一个智能指针,而不是一个原始指针.正如我的教授总是说,如果你不知道你在C/C++中做了什么,最好不要这样做!
使用boost::scoped_ptr,享受异常安全,自动内存管理,零开销和NULL检查:
struct test
{
int var;
void fun()
{
std::cout << var;
}
};
int main()
{
boost::scoped_ptr<test> p(NULL);
p->fun(); // Assertion will fail, Happy debugging :)
}
Run Code Online (Sandbox Code Playgroud)