std::cout 一个 null char* 指针如何中止程序? [复制]

Posted

技术标签:

【中文标题】std::cout 一个 null char* 指针如何中止程序? [复制]【英文标题】:how does std::cout a null char* pointer abort the program? [duplicate] 【发布时间】:2017-09-29 03:02:48 【问题描述】:

我尝试在屏幕上打印一个 nullptr,并且:

int* ptrA = nullptr;
std::cout<<ptrA<<"\n"; // print 0
char* ptrB = nullptr;
std::cout<<ptrB<<"\n"; // print nothing, program exit with code 0
... // never execute

我认为编译器 (g++ 4.8.4) 可能会警告我不应该尝试计算 nullptr。事实是:程序中止,'/test has exited with code 0 (0x00000000)',就像它正常终端一样。

为什么?我的意思是,如果我做错了什么,或者这样做的目的是什么?

谢谢


感谢大家,我知道行为可能是未定义的, 让 char* 成为字符串,或打印地址。 并被建议永远不要这样做。 我只是想知道为什么程序没有告诉我任何东西,比如警告、断言或使用 -1 之类的代码退出,或者其他任何东西。 是编译器的设计行为吗?

【问题讨论】:

简单的答案是,这不是一个非常高优先级的事情。 C++ 经常错误地假设程序员知道他们在做什么并且提供很少的训练轮。您可能会发现一些有趣的东西:gcc.gnu.org/bugzilla/show_bug.cgi?id=16351您可能还会阅读一些关于静态分析和误报的困难的文章。 我打赌它确实以代码-1(或其他代码)退出 【参考方案1】:

char*s 是 C 中的规范字符串实现,不幸的是它们在 C++ 中也很常见。

由于这个原因,输出char* 不会输出该指针所持有的地址,而是会打印该指针所指向的字符串

实现可能如下所示:

std::ostream& operator<<(std::ostream& os, const char* data)

  while (*data)
  
    os << *data;
    data++;
  
  return os;

由于它取消引用您提供给它的指针,因此将 (char*)nullptr) 传递给此函数会调用未定义的行为,在这种情况下,中止与其他任何行为一样好。

【讨论】:

(别忘了*data++ @Dúthomhas,哎呀,我的错 你的意思是在那个循环中放一个 ++ 吗? @templatetypedef,你是什么意思? 没关系 - 你修好了。【参考方案2】:

在处理ostream 时,char* 与其他类型的指针不同,因为有一个operator&lt;&lt; 专门设计用于将char* 视为以null 结尾的C 字符串。

您的程序中止,因为您正在传递 operator&lt;&lt; 一个 char* 指针:

指向不属于你的内存,或 指向您拥有的内存,但不是正确的以空字符结尾的 C 字符串,或者 为空

所有这些都会调用未定义的行为,这意味着编译器对你非常友好,只需中止你的程序而不是做一些可怕的事情。

要打印char* 指针的值,请将其强制转换为void*

【讨论】:

您没有在列表中提到这一点,但是将 NULL char* 指针传递给 operator&lt;&lt;未定义的行为,如果 operator&lt;&lt; 也可能导致终止取消引用它 中止程序的不是编译器。更有可能的是,使用无效输入调用 operator&lt;&lt; 会导致抛出未被捕获的异常。未捕获的异常会调用std::terminate(),默认情况下会调用std::abort() 来中止程序。 LOL,OP 的简化总是得到反馈。是的,运行时正在中止程序;我认为运行时执行编译器设计的工作。

以上是关于std::cout 一个 null char* 指针如何中止程序? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

4.signed/unsigned char

带有 char、double、int 和 t 的结构的大小 [重复]

根据typedef可以是wcout的通用cout

C++基础 为什么不能cout一个string

带有 std::cout 的多线程控制台文本动画

如何将std :: string复制到unsigned char数组?