cout打印包含多于字符长度的字符的char []?

时间:2018-01-20 12:26:25

标签: c++ gcc

#include<iostream>
using namespace std;
int main(void)
{
    char name[5];
    cout << "Name: ";
    cin.getline(name, 20);
    cout << name;
}

输出:

Name: HelloWorld
HelloWorld

这不应该出错吗?

当我写一个更长的字符串时,

Name: HelloWorld Goodbye
HelloWorld Goodbye

cmd退出并显示错误。

这怎么可能?

编译器:G ++(GCC 7),Nuwen 操作系统:Windows 10

5 个答案:

答案 0 :(得分:1)

它被称为缓冲区溢出,是代码错误和漏洞的常见来源。开发人员有责任确保不会发生这种情况。字符串将被打印,直到它们到达第一个'\ 0'字符

答案 1 :(得分:0)

代码产生“未定义的行为”。这意味着,任何事情都可能发生在您的情况下,该程序意外地工作。但是,它可能会对不同的编译器标志或不同的系统执行完全不同的操作。

  

这不应该是错误或其他什么。

没有。编译器无法知道您将输入一个长字符串,因此不会有任何编译器错误。您也不会在此处抛出任何运行时异常。您可以确保程序可以处理长字符串。

答案 2 :(得分:0)

您的代码遇到了UB,也称为未定义行为,正如维基百科所定义的那样,执行计算机代码的结果,其行为不是代码所遵循的语言规范所规定的。它通常发生在您正确记录定义变量时,在这种情况下是一个太小的char数组。

答案 3 :(得分:0)

Even -Wall标志不会发出任何警告。因此,您可以使用valgrindgdb等工具来检测内存泄漏和缓冲区溢出

答案 4 :(得分:0)

您可以查看这些问题:

Array index out of bound in C

No out of bounds error

他们有合格的答案。

我的简短回答,基于我发布的问题中已经提到的那些:

  • 您的代码实现了Undefined Behavior(缓冲区溢出),因此在运行一次时它不会出错。但其他时间可能会给。这是一个机会。
  • 当你输入一个更长的字符串时,你实际上破坏了程序的内存(堆栈)(即你覆盖了应该包含一些程序相关数据和你的数据的内存),所以你的程序的返回代码最终不同于0,它解释为错误。弦越长,搞砸的可能性就越高(有时甚至是短弦都会搞砸)

您可以在此处阅读更多内容:https://en.wikipedia.org/wiki/Buffer_overflow