为什么在C++中发生这种情况?

Hal*_*oum 1 c++ g++ undefined-behavior

我在不同平台上使用G ++(4.5.2)遇到了一个非常奇怪的行为; 这是代码:

class Class
{
private:
  std::string rString;

public:
  Class()
  {
    this->rString = "random string";
    std::cout << "Constructor of Class" << std::endl;
  }

  virtual ~Class()
  {
    std::cout << "Destructor of Class" << std::endl;
  }

  void          say() const
  {
    std::cout << "Just saying ..." << std::endl;
    if (this == NULL)
      std::cout << "Man that's really bad" << std::endl;
  }

  void          hello() const
  {
    std::cout << "Hello " << this->rString << std::endl;
  }

};


int     main()
{
  Class *c = NULL;

  /* Dereferencing a NULL pointer results
     in a successful call to the non-static method say()
     without constructing Class */
  (*c).say(); // or c->say()

  /* Dereferencing a NULL pointer and accessing a random
     memory area results in a successful call to say()
     as well */
  c[42000].say();

  /* Dereferencing a NULL pointer and accessing a
     method which needs explicit construction of Class
     results in a Segmentation fault */
  c->hello();

  return (0);
}
Run Code Online (Sandbox Code Playgroud)

问题是,为什么main函数中的两个第一个语句不会使程序崩溃?这是未定义的行为,还是编译器只是调用Class :: say()就好像它是静态的,因为它不会在方法中取消引用"this"指针?

GMa*_*ckG 10

是的,这是未定义的行为.您不能使用空指针调用成员函数.

在实践中,前两个确实起作用,因为this它永远不会被解除引用,因此你的未定义行为不必像在第三个中那样表现出来,其中内存确实被错误地访问了.

(在所有情况下,每次调用时你都会死掉一点,所以不要这样做.)


Omn*_*ity 6

未定义的行为仅表示未定义的内容.这并不意味着"崩溃".

未定义的行为可以做任何事情,包括以你想要的方式工作.