2013-04-25 103 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不訪問成員變量並且是非虛函數。