当我尝试用GCC编译使用gets()函数的C代码时,我得到这个警告:
(.text+0x34):警告:' gets'函数是危险的,不应该使用。
我记得这与堆栈保护和安全性有关,但我不确定确切的原因。
我如何删除这个警告,为什么使用gets()会有这样的警告?
如果gets()是如此危险,那么为什么我们不能删除它?
当我尝试用GCC编译使用gets()函数的C代码时,我得到这个警告:
(.text+0x34):警告:' gets'函数是危险的,不应该使用。
我记得这与堆栈保护和安全性有关,但我不确定确切的原因。
我如何删除这个警告,为什么使用gets()会有这样的警告?
如果gets()是如此危险,那么为什么我们不能删除它?
当前回答
因为gets在从stdin获取字节并将它们放到某个地方时不会做任何检查。举个简单的例子:
char array1[] = "12345";
char array2[] = "67890";
gets(array1);
首先,你可以输入你想要的字符数,get不会关心它。其次,字节超过数组的大小(在本例中为array1)将覆盖它们在内存中找到的任何内容,因为gets将写入它们。在前面的例子中,这意味着如果你输入"abcdefghijklmnopqrts"可能,不可预知的,它也会覆盖array2或其他东西。
该函数是不安全的,因为它假定输入一致。永远不要用它!
其他回答
我最近在comp.lang.c的一篇USENET文章中读到,gets()将从标准中删除。哦吼
你会很高兴知道 委员会刚刚投票(一致通过) 将gets()从 还有草案。
在C11(ISO/IEC 9899:201x)中,gets()已被删除。(在ISO/IEC 9899:1999/ co .3:2007(E)中已弃用)
除了fgets(), C11引入了一个新的安全替代gets_s():
C11 K.3.5.4.1 gets_s函数 #定义__STDC_WANT_LIB_EXT1__ # include < stdio . h > (Char *s, rsize_t n);
但是,在推荐实践部分中,fgets()仍然是首选。
fgets函数也允许正确编写的程序安全地处理输入行 在结果数组中存储。一般来说,这要求打电话的人得到报酬 注意结果数组中是否存在换行字符。考虑 使用fget(以及任何基于换行符的必要处理)而不是 gets_s。
gets() is dangerous because it is possible for the user to crash the program by typing too much into the prompt. It can't detect the end of available memory, so if you allocate an amount of memory too small for the purpose, it can cause a seg fault and crash. Sometimes it seems very unlikely that a user will type 1000 letters into a prompt meant for a person's name, but as programmers, we need to make our programs bulletproof. (it may also be a security risk if a user can crash a system program by sending too much data).
Fgets()允许您指定从标准输入缓冲区中取出多少字符,以便它们不会溢出变量。
C语言的gets函数是危险的,是一个代价非常高昂的错误。Tony Hoare在他的演讲“Null References: The Billion Dollar Mistake”中特别提到了这一点:
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
整个小时都值得一看,但他从30分钟开始的评论观点在39分钟左右受到了批评。
希望这能激发你对整个演讲的兴趣,让你注意到我们如何需要语言中更正式的正确性证明,以及语言设计者如何应该为他们语言中的错误而受到指责,而不是程序员。这似乎是糟糕语言的设计者打着“程序员自由”的幌子把责任推给程序员的全部可疑原因。
fgets。
从stdin读取:
char string[512];
fgets(string, sizeof(string), stdin); /* no buffer overflows here, you're safe! */