【问题标题】:Is strncpy() a specialization of memcpy()?strncpy() 是 memcpy() 的特化吗?
【发布时间】:2011-06-28 16:01:42
【问题描述】:

只是想知道(因为我们经常使用这些功能)。我看不出strncpy()memcpy() 之间有任何实际区别。不值得这么有效的说,

char* strncpy (char *dst, const char *src, size_t size)
{
  return (char*)memcpy(dst, src, size);
}

或者我错过了任何副作用?有一个类似的earlier question,但找不到确切的答案。

【问题讨论】:

    标签: c++ c standard-library


    【解决方案1】:

    有区别,请参阅您链接到的strncpy 页面的这一部分(强调我的):

    将源的前 num 个字符复制到目标。 如果源 C 字符串的结尾(由空字符表示)在复制 num 个字符之前找到,则用零填充目标,直到总共已写入 num 个字符。

    所以如果要复制的字符串短于限制,strncpy 用零填充,而memcpy 读取超出限制(可能调用未定义的行为)。

    【讨论】:

    • 这具有确保超出源字符串末尾没有访问内存的重要作用。如果字符串位于内存末尾,memcpy 可能会导致访问冲突。
    • 另请注意,与 strlcpy 不同的是,strncpy 使用定义的值写入所有目标位置。
    【解决方案2】:

    不,它们不一样。

    来自 C 标准(ISO/IEC 9899:1999 (E))

    7.21.2.3 strcpy 函数

    说明

    2 strncpy 函数复制不超过 n 个字符(null 后面的字符) 字符不被复制)从 s2 指向的数组到 s1.260 指向的数组)如果复制发生在重叠的对象之间,则行为未定义。
    3 如果 s2 指向的数组是一个短于 n 个字符的字符串,则将空字符附加到 s1 指向的数组的副本中,直到 n 个字符全部被写入。
    退货
    4 strncpy函数返回s1的值。

    7.21.2.1 memcpy函数
    说明

    2 memcpy 函数将 s2 指向的对象中的 n 个字符复制到 s1 指向的对象中。如果复制发生在重叠的对象之间,则行为未定义。
    退货 3 memcpy函数返回s1的值。

    当使用memcpy() 时,源缓冲区和目标缓冲区可以重叠,而在strncpy() 中不能发生这种情况。

    根据 C 标准,重叠缓冲区的行为对于 strncpy()memcpy() 都是未定义的。

    根据 C 标准,strncpy()memcpy() 的真正区别在于,如果源字符串小于 N 值,则将 NULL 字符附加到剩余的 N 数量。

    memcpy() 效率更高,但安全性较低,因为它不会检查源以查看是否有 N 个数量可以移动到目标缓冲区。

    【讨论】:

    • +1 以获得良好的参考。我只是错过了那个空字符部分
    【解决方案3】:

    不,strncpy() 不是特化,因为它会在复制和停止过程中检测到 '\0' 字符,而 memcpy() 不会这样做。

    【讨论】:

      【解决方案4】:

      除了其他人所说的之外,src 和 dst 指针的类型无关紧要。也就是说,我可以将一个 4 字节整数复制到 1 字节的 4 个连续字符,如下所示:

      int num = 5;
      char arr[4];
      memcpy(arr, &num, 4);
      

      另一个区别是 memcpy 不查找任何字符(例如 NULL,由 strncpy 提供)。它盲目地将 num 个字节从源复制到目标。

      已编辑:正确格式化代码

      【讨论】:

      • 你测试过你的代码吗?你的意思是memcpy(arr, &num, 4);
      【解决方案5】:

      您可以通过检查 \0 并且不复制该点来使 strncpy 更快。所以 memcpy 总是会复制所有数据,但 strncpy 通常会因为检查而更快。

      【讨论】:

      • 但也有人会争辩说,如果您知道字符串长度,只复制长度字节而不检查每个字节是否为 '\0' 会更快。
      猜你喜欢
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2019-06-15
      • 2017-09-15
      • 1970-01-01
      • 2016-01-28
      • 2018-10-08
      相关资源
      最近更新 更多