C strn*()与str*()相比有多快?
可能重复:C strn*()与str*()相比有多快?,c,performance,optimization,C,Performance,Optimization,可能重复: 我正在读一本关于计算机/密码等的书,作者经常使用strncpy(dest,src,strlen(src))而不是strcpy(dest,src)这对我来说没什么意义。。嗯,我是一名专业程序员 问题是:这真的有什么不同吗?真正的应用程序使用这样的东西?strn系列的原因是防止缓冲区溢出。如果您从调用方传递数据,并且盲目地相信它正确地以null结尾,并且不会使要将其复制到的缓冲区溢出,那么您将被缓冲区溢出攻击所拥有 效率差异可以忽略不计。strn系列可能会稍微慢一些,因为它需要不断检查
我正在读一本关于计算机/密码等的书,作者经常使用
strncpy(dest,src,strlen(src))代码>而不是strcpy(dest,src)代码>这对我来说没什么意义。。嗯,我是一名专业程序员
问题是:这真的有什么不同吗?真正的应用程序使用这样的东西?strn系列的原因是防止缓冲区溢出。如果您从调用方传递数据,并且盲目地相信它正确地以null结尾,并且不会使要将其复制到的缓冲区溢出,那么您将被缓冲区溢出攻击所拥有
效率差异可以忽略不计。strn系列可能会稍微慢一些,因为它需要不断检查您是否溢出。strncpy(dest,src,strlen(src));与strcpy(dest,src)相同;所以这里没有区别,但是
Strcpy可能会导致安全漏洞,因为您不知道字符串的长度。聪明的人可以用它覆盖服务器上的内容。作者几乎肯定滥用了strn*
功能。不幸的是,使用strn*
函数几乎没有什么好的理由,因为它们实际上并不能满足您的需要
让我们看一下strcpy和strncpy
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
strcpy
函数将src
复制到dest
中,包括一个尾部\0
。它很少有用:
除非您知道源字符串适合目标缓冲区,否则会出现缓冲区溢出。缓冲区溢出是安全隐患,它们会使程序崩溃,并导致程序行为不正确
如果您确实知道源字符串和目标缓冲区的大小,那么最好使用memcpy
相比之下,strncpy
最多将src
的n
字节复制到dest
中,然后用\0
填充其余字节。它很少有用:
除非您知道源字符串小于目标缓冲区,否则无法确定生成的缓冲区将以nul终止。如果假设结果是nul终止的,则这可能会导致程序中的其他地方出错
如果您确实知道源字符串更小,那么您也可以使用memcpy
您可以在调用strncpy
后简单地终止字符串,但是您确定要以静默方式截断结果吗?我想大多数时候,你宁愿有一条错误信息
这些功能为什么存在?
strcpy函数偶尔很方便,但它主要是人们不太关心验证输入的时代遗留下来的。向程序输入太大的字符串会使程序崩溃,建议是“不要这样做”
当您希望在固定大小的字段中传输数据,并且不希望在字段的其余部分中放入垃圾时,strncpy
函数非常有用。这主要是人们使用固定大小字段的时代遗留下来的
因此,在现代C软件中,您很少会看到strcat
或strncpy
更糟糕的问题
然而,你的例子结合了两个世界中最糟糕的一面。让我们检查一下这段源代码:
strncpy(dest, src, strlen(src));
这会将src
复制到dest
,中,不带\0
终止符,也不带边界检查。它结合了strcpy的最坏方面(无边界检查)和strncpy的最坏方面(无终止符)。如果您看到这样的代码,请走开
如何使用字符串
好的C代码通常使用以下几个选项之一来处理字符串:
使用固定缓冲区和snprintf
,只要您不介意固定缓冲区
使用有界字符串函数,如strlcpy
和strlcat
。这些是BSD扩展
使用跟踪字符串长度的自定义字符串点,并使用memcpy
和malloc
编写自己的函数
如果代码是书中的逐字复制,那么作者要么不懂C,要么不是安全专家,要么两者兼而有之
也可能是他使用了错误配置的编译器,明确禁止使用某些已知的潜在不安全函数。当编译器无法区分安全性、不安全性和潜在不安全性时,这是一种值得怀疑的做法,并且一直在妨碍它。对strcpy使用strncpy与它的执行速度关系不大,但strncpy大大降低了缓冲区溢出攻击的可能性。
在C语言中,指针是最强大的,但它们也使系统易受攻击
下面摘自一本优秀的黑客校对书,可能会对您有所帮助
许多溢出错误是错误的字符串操作造成的。电话,如
strcpy()在复制字符串之前不检查其长度。结果是
可能发生缓冲区溢出。预计将出现空终止符
出席。从某种意义上说,攻击者依靠此漏洞来利用
机器;但是,这也意味着攻击者注入的缓冲区也必须
不能有空字符。如果攻击者插入空字符,则
字符串复制将在插入整个有效负载之前终止。我不明白为什么strncpy(dest,src,strlen(src))代码>将比strcpy(dest,src)快
@Mystical它的速度是一样的(尽管strlen增加了使用它的开销)。速度不是使用它的原因。防止缓冲区溢出是首选的原因。(strncpy
的速度与strcpy
的速度相同。假设复制的字符数量相同,则内部的速度相同