2015-03-02 81 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

相关问题