Des*_*tor 2 c strcpy strcat c11
C11&C++14标准已经删除gets()了本质上不安全的功能并导致安全问题,因为它不会在缓冲区溢出中执行边界检查结果.那为什么C11标准不掉线strcat()和strcpy()功能?strcat()函数不检查第二个字符串是否适合第一个数组.strcpy()函数也不包含检查目标数组边界的规定.如果源数组有多于目标数组可以容纳的字符怎么办?程序很可能会在运行时崩溃.
那么,如果这两个不安全的函数完全从语言中删除,那不是很好吗?为什么他们仍然存在?是什么原因?只有像这样的功能不是很好strncat(),strncpy()吗?如果我没有错,Microsoft C&C++编译器提供了这些功能的安全版本strcpy_s(),strcat_s().那么为什么他们没有正式实施其他C编译器来提供安全性呢?
Kei*_*son 11
gets()本质上是不安全的,因为一般情况下,如果接收到太多数据,它可能会溢出目标stdin.这个:
char s[MANY];
gets(s);
Run Code Online (Sandbox Code Playgroud)
如果MANY输入了多个字符,将导致未定义的行为,并且程序通常无法阻止它.
strcpy()并且strcat()可以完全安全地使用,因为只有当源字符串太长而无法包含在目标数组中时,它们才会溢出目标.源字符串包含在程序本身控制的数组对象中,而不是任何外部输入.例如,这个:
char s[100];
strcpy(s, "hello");
strcat(s, ", ");
strcat(s, "world");
Run Code Online (Sandbox Code Playgroud)
除非程序本身被修改,否则不可能溢出.
strncat()可以用作更安全的版本strcat()- 只要你正确指定第三个参数.一个问题strncat()是它只给你一种方法来处理目标数组中没有足够空间的情况:它默默地截断字符串.有时这可能是您想要的,但有时您可能想要检测溢出并对其执行某些操作.
至于strncpy(),是不是只是一个更安全的版本strcpy().它本身并不危险,但是如果你不是很小心,你可以很容易地离开目标数组而没有终止'\0'空字符,导致下次将它传递给期望指向字符串的指针的函数时出现未定义的行为.事实上,我已经写过这个.
strcpy与... strcat不相似gets.问题gets是,它用于从输入读取,因此程序员控制是否会有缓冲区溢出.
C99 Rational解释strncpy为:
国际标准的基本原理 - 编程语言 - C§7.21.2.4
strncpy函数
strncpy最初被引入C库以处理诸如目录条目之类的结构中的固定长度名称字段.这些字段的使用方式与字符串不同:对于最大长度字段,尾部空值不是必需的,而将较短的5个字符的尾随字节设置为空可确保有效的字段比较.strncpy并非原产地是"有界的strcpy",委员会倾向于认识到现有的做法而不是改变功能以更好地适应这种用途.