空指针对象问题

Rob*_*ide 1 c++

嗨,有人可以告诉为什么在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的角落:虚拟功能是另一回事.


Ara*_*raK 7

未定义的行为,因为您正在访问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)

  • 好吧,防止空指针相对简单.在最简单的情况下,可以完全删除空指针(通过不使用它们;通常,这非常有效).为自己的无能指责语言并不是真正有建设性的...... C++有很多不足之处. (11认同)
  • 这将要求运行时系统检查"NULL"指针 - 这违背了C++的精神.(您不希望在显卡驱动程序的内部循环中进行这些检查.) (8认同)
  • @Avishay:反过来说:语言希望程序员不要尝试在NULL指针上执行func().该语言表示您不允许这样做.它没有说明如果你这样做会发生什么,它相信你不会做不允许的事情. (2认同)
  • 哇所以语言很糟糕,因为它不能做你想做的事情,即使你以一种你不应该的方式使用它.伟大的思维方式.每次执行NULL检查的速度都很慢,大部分时间都不需要,因为程序员应该知道他在做什么.如果你真的需要它,只需添加它. (2认同)
  • @_Avishay:很抱歉,但我不想因为你作为程序员吮吸而支付检查每个指针是否为NULL的代价.我知道我的代码是有效的,为什么我要付出额外的代价(用较慢的代码)来支持你(重新缺乏经验)? (2认同)