为什么这个C ++ char数组似乎能容纳超过它的大小?

时间:2010-05-22 18:49:45

标签: c++ g++ char

#include <iostream>
using namespace std;

typedef struct
{
    char streetName[5];

} RECORD;

int main()
{
    RECORD r;
    cin >> r.streetName;
    cout << r.streetName << endl;

}

当我运行这个程序时,如果我输入超过5个字符,输出将显示我输入的整个字符串。它不会截断5个字符。那是为什么?

如何让它正常工作?

7 个答案:

答案 0 :(得分:13)

你正在溢出缓冲区。在streetName之后放置另一个char数组,你可能会发现它获得了其余的字符。现在你只是破坏堆栈上的一些内存。

答案 1 :(得分:6)

为了将输入限制为接收阵列的大小,您需要使用输入法提供的长度限制功能。在您的情况下,您使用的是cin,这意味着您可以使用width方法指定限制

cin.width(5);    
cin >> r.streetName;

答案 2 :(得分:5)

因为你的缓冲区结束了,在这种特殊情况下,你正在逃避它。 C和C ++使"shoot yourself in the foot"变得非常容易,但这并不意味着你应该这样做。

答案 3 :(得分:5)

因为cin将streetName视为char *并写入内存,所以没有什么可以停止写入*(streetName + 6)以及更进一步。这是缓冲区溢出的一种形式

在这种情况下,最好的代码是将streetName定义为std :: string

即。

typedef struct
{
        std::string streetName;
} RECORD;

答案 4 :(得分:3)

这是buffer overrun

答案 5 :(得分:3)

在c ++中正确执行此操作的方法是使用std :: string。

#include<iostream>
#include<string>

....
std::string r;
getline(cin, r);
std::cout << r <<std::endl;

对于截断输入(具有适当定义和输入的值)。

while(cin.peek() != EOF && i < len)
{
  cin >> arr[i];
  ++i;
}

如果你打算用它做其他的事情,你会想要在此之后做一些事情来刷新缓冲区,而不是让剩下的行留在输入流上。

答案 6 :(得分:3)

C ++不对数组访问执行边界检查,内存不会简单地停在数组的末尾。您正在将数据写入不属于数组的内存中,其后果是非确定性的,有时甚至可能出现

如果您将该代码放入函数中,很可能在您尝试从函数返回时程序会崩溃,因为很可能您将转储到堆栈上的函数返回地址。您可能还有属于调用函数的数据已损坏。