【问题标题】:char* p=NULL, cout<<p; gives exceptionchar* p=NULL, cout<<p;给出例外
【发布时间】:2015-05-02 09:59:13
【问题描述】:

我最近在一次采访中被问到这个问题:

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 等,它按预期工作。 有人可以解释一下吗? 感谢您的帮助!

【问题讨论】:

标签: c++ pointers char


【解决方案1】:

std::cout::operator&lt;&lt;char* 重载需要一个以 null 结尾的 C 字符串。这就是它试图访问指针的原因。

要绕过此行为,请先将指针转换为 void*

【讨论】:

    【解决方案2】:

    当然,在最简单的解释中,cout 尝试尊重指针并打印字符串,因为您传递了一个 char 指针

    理解这一点的最好方法是遵循一段代码。

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

    它会输出“llo”,因为第一个预感类似于“第一个 l 的打印地址”

    【讨论】:

      【解决方案3】:

      输出流知道,当您传递char* 时,您想要打印一个字符串。您传递了一个未初始化的指针。它试图将其读取为 C 字符串……而且,这会引发未定义的行为。

      如果您想先打印一个转换为void* 的地址,即static_cast&lt;void*&gt;(p)

      顺便说一句,NULL 不能保证评估为0(在所有0 位意义上)。但是,可以保证同等0 进行比较。不是一回事。此外,您的增量也会调用 UB。

      【讨论】:

      • 你有没有 NULL 没有被定义为 0 的例子?人们总是这么说,但这样做没有合乎逻辑的理由。
      • @Brett:我有一个规格,就像你一样。这并不意味着它在实践中不起作用,它只是意味着如果你可以避免它,你不应该编写依赖它的代码。
      • 最近的 C++ 建议使用关键字 nullptr,而不是 NULL 或 0。
      猜你喜欢
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 2011-03-07
      • 2012-05-21
      相关资源
      最近更新 更多