cin.get(name,30)调整char名称[10]?

时间:2015-11-29 15:04:20

标签: c++

我写了这段代码,但我不明白为什么char []允许我存储超过10个字符,如果你的大小仍然是10? 通常是什么函数cin.get()启用它?

#include <iostream>
using namespace std;

int main(){
char name[10];

cout<<"enter name: ";

cin.get(name,30);

cout<<"char[]: "<<name<<endl;

cout<<"size: "<<sizeof name;

return 0;
}

2 个答案:

答案 0 :(得分:2)

简单地说,因为它是C ++。该语言的设计反映了其早期的硬件,其中几个字节的内存是宝贵的(这在一些特殊的环境中仍然非常有用,例如嵌入式硬件)。为了让您最大限度地控制内存管理,您作为程序员有很多关于内存分配(和解除分配!)的地方和时间,这意味着您还必须自己完成一些相关的簿记。

在这种情况下,如果您保留10个字符的内存然后告诉另一个函数它可以写30个字节,它将相信您传入的变量已经准备好了。它确实意味着你在内存中写入了未分配给你的内容(读取:将会在你最不期望的时候)具有令人讨厌的副作用,例如巧妙地改变变量值或者只是简单地使你的程序崩溃。

cin.get这样的函数接受缓冲区大小的原因是你需要告诉它们可以使用多少内存 - 而且应该永远不会超过你分配的内存。如果你想避免这种情况,你可以使用像std::string这样的类,试着把这些低级别的东西拿走。

答案 1 :(得分:1)

这是未定义的行为。 C ++标准没有定义如果你这样做会发生什么。

从C ++ 14标准草案N4296,§1.3.24:

  

允许的未定义行为的范围可以忽略这种情况   完全具有不可预测的结果,在翻译过程中表现出色   要么   程序以环境特征的文件形式执行(有或没有发行   诊断消息),终止翻译或执行(用   发布诊断信息。)

您可能会低于标准的一级,即操作系统,除了其他内容之外,它还负责内存管理。
缓冲区name分配在堆栈上,紧邻stack frames自动变量线程局部变量。 调用cin.get(name, 30)时,可以在数组的边界上写入数据,有效地覆盖我枚举的数据。甚至可能会发生呼叫尝试写入堆栈边界,这几乎肯定会被操作系统捕获。