我有一个代码
char s[5];
cin >> s;
cout << strlen(s);
cout << endl;
cout << s;
即使我输入超过5个字符,例如“qwertyui”,它也能正常工作。这是否意味着我使用的是未分配的内存?
答案 0 :(得分:2)
strlen(s)
是某些内容,但与5
无关。 strlen
适用于C字符串,是字符数组,但它们的长度定义为第一个零字节发生之前的字符数。
现在,你的第二行中的cin
无法知道你的char[]
有多长,所以它只接受尽可能多的输入。您必须永远不会使用char缓冲区进行您不知道格式正确的输入。您所看到的是缓冲区溢出正在运行中。在不属于您分配的任何变量的内存上进行写入会导致未定义的行为,因此您的程序可能正常工作,因为一个段错误(访问操作系统从未给你的内存),或覆盖进程内存的现有部分,或者......只是做任何事情,因为它确实未定义。
所以,你在写C ++,而不是C.只是
string s;
cin >> s;
cout << s.length()
<< endl
<< s;
避免处理(非常危险的)C字符串。
答案 1 :(得分:0)
你是对的,如果你写的超过5个字符,它仍然可以正确回显。你只是简单地写下缓冲区的末尾,然后只是为分配给char s[5]
的内存旁边的内存进行爆破。这很糟糕,原因很多,包括安全漏洞。有关详细信息,请参阅here。
如果您无法使用string
(无论出于何种原因),请使用fgets
。有关fgets
的文档及其使用方法,请参阅here。 绝对不使用 gets
。它几乎等同于您上面所做的,请参阅here for why gets is so dangerous。