2013-04-25 67 views
2

我创建了一个NULL类指针应用程序,但不知何故NULL对象(的应用程序)的方法正在工作。这里是我的代码:空指针的奇怪行为

#include "App.h" 
#include <iostream> 
using namespace std; 
int main() 
{ 
    App* pointer = NULL; 
    pointer->print(); 

    system("pause"); 
} 

附加头文件

#pragma once 
#include <iostream> 
using namespace std; 
class App 
{ 
private: 
    int x; 
    int y; 
public: 
    App(void); 
    ~App(void); 
    App(int a, int b) 
    { 
     x=a; 
     y=b; 
    } 
    void print() 
    { 
     cout<<"hello world"<<endl; 
    } 
}; 

运行中产生的画面:hello world。这是为什么?

+0

尝试使用函数中的某个成员变量,并可能发生某些情况。 – 2013-04-25 14:25:18

回答

2

未定义的行为就是这样 - 未定义。任何事情都可能发生,包括表现正确。

对于您的情况,具体而言,您可能希望从程序中检出生成的程序集。您可能会发现编译器已经优化了您的代码,并将该打印输出内联或直接调用,而不是通过指针/表查找实际调用它。

+0

但是为什么?没有合理的解释? – 2013-04-25 14:26:07

+0

你必须看看你的编译器做了什么来弄清楚(参见我的第二段)。恐怕,你的问题没有足够的信息让我们继续前进。 – 2013-04-25 14:26:45

+4

@bennyperl您可能还会注意到,编译器将方法视为相对标准的函数调用,只是简单地通过寄存器或第一个参数传递'this'指针。由于有问题的函数没有访问'this',它会盲目地不会注意到'nullptr'' this'。由于C++标准规定了您所做的是未定义的行为,因此编译器可以自由生成代码,执行所需的任何操作 - segfault,格式化硬盘驱动器,将您的银行帐户信息发送给Aruba - 或者在此情况下忽略'this'指针是'nullptr'。依靠这是一个坏主意。 – Yakk 2013-04-25 14:27:01

1

NULL指针上调用方法是未定义的行为,所以可能发生任何事情。你永远不应该指望代码将始终产生这个输出的事实。总是尽量避免这种情况。

1

取消引用NULL指针是未定义的行为。你不应该期望你的程序不会因为你这样做而“工作”。

在这种情况下,您的打印功能不会“使用”this指针,以便您的代码按预期执行。但是你不应该依赖这个,未定义的行为就意味着它所说的。

0

因为打印不会(甚至隐式地)访问“this”指针后面的任何数据。

1

这是undefined behavior,这thread解释了为什么它最有可能的工作,基本的解释是,它可能会被改造成类似于:

void _App_print(App* this); 

因为你没有使用this它的工作原理。

1

这是未定义的行为。该实现能够在这个玩具示例中工作,因为print不访问成员变量并且是非虚函数。