Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C strn*()与str*()相比有多快?_C_Performance_Optimization - Fatal编程技术网

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
    的速度相同。假设复制的字符数量相同,则内部的速度相同