2015-03-02 79 views
0

最近,我問這個問題在接受採訪時:char * p = NULL,cout << p;給人例外

char* p = NULL; 
cout << p << endl; 
++p; 
cout << p << endl; 

我給出的答案是第一COUT將打印00000,接下來將打印00001 但是,當我在Visual Studio中選中它,它提供了一個異常: StringFunctions.exe中0x009159F1的第一次機會異常:0xC0000005:訪問衝突讀取位置0x00000000。 StringFunctions.exe中0x009159F1未處理的異常:0xC0000005:訪問衝突讀取位置0x00000000。

但它的預期工作如int,float等 有人可以解釋這個嗎? 感謝幫助!

+0

未定義的行爲。 http://stackoverflow.com/a/19180731/1462718和http://stackoverflow.com/a/394774/1462718請參閱「請注意遞增包含空指針值嚴格的指針是未定義的行爲」。 – Brandon 2015-03-02 05:31:37

+0

這不是提議的線程的重複。當OP通過增加空指針來調用UB時,他主要關心如何打印指針的地址。 – 2015-03-02 19:16:49

回答

3

char*std::cout::operator<<的過載需要以空字符結尾的C字符串。這就是爲什麼它試圖訪問指針。

要繞過此行爲,請首先將指針投射到void*

0

當然,在最簡單的解釋,COUT試圖尊重指針和打印字符串,因爲你通過一個字符指針

理解這一點的最好辦法是下面的一段代碼。

char *s = "hello"; 
cout << s+2 << endl; // Or &s[2] 

它將輸出「LLO」,其中作爲第一直覺會是這樣的「第l打印地址」

2

輸出流知道,當你通過一個char*,你要打印串。你傳遞了一個未初始化的指針。它試圖將它看作一個C字符串......並且,它調用了未定義的行爲。

如果您想打印首先投射到void*的地址,即static_cast<void*>(p)

另外,NULL不保證評估爲0(在全部0位意義上)。然而,保證將同樣地0進行比較。不是一回事。此外,您的增量也會調用UB。

+0

你有沒有將NULL定義爲0的情況的例子?人們總是這樣說,但沒有合乎邏輯的理由去做。 – developerbmw 2015-03-02 06:39:26

+0

@Brett:我有一個規範,和你一樣。這並不意味着它不會在實踐中發揮作用,它只意味着如果可以避免的話,就不應該編寫代碼。 – 2015-03-02 06:52:36

相關問題