3

来自cplusplus.com关于memcpy:“该函数不检查源中的任何终止空字符 - 它总是精确复制 num 个字节。”

所以下面的代码应该给出一个运行时错误,不是吗?

char str1[20] = "";
char str2[20] = "Another Text---";

memcpy(str1, str2, strlen(str2));
printf("%s\n%s", str1, str2);

但是我总是用我的 gcc 编译器从这段代码中得到正确的输出。这是否意味着 memcpy 实际上从末尾复制空字符,str2或者它只是一个随机情况?

编辑:我得到与 相同的行为str1[20] = "A",因为一些答案指出str1[20] = ""正在用所有 NULL 字符初始化字符串。

4

4 回答 4

15

谜题中的关键成分是初始化器""。这等同于:

char str1[20] = { 0 };

这又与(至少在 GCC 中,并且始终在 C++ 中)相同:

char str1[20] = { };

或者

char str1[20] = { 0, 0, 0, ..., 0 };   // 20 times

所有这些初始化程序都将数组初始化为包含 20 个零。

memcpy调用不会复制空终止符(因为strlen不计算它),但目标数组首先被正确清零,所以一切都很好。

于 2012-09-20T18:20:40.637 回答
1

memcpy 正在将 strlen(str2) (但这并不意味着将空字节复制)字节从 str2 复制到 str1。由于 str1 中有足够的空间容纳这么多字节,因此它可以工作。memcpy完全按照它所说的复制内存。

如果您尝试将超过 20 的任何内容从一个复制到另一个,则会出现错误。您也不应该在任一变量中存储超过 19 个字符。

正如 kerrek 解释的那样,它还可以帮助您将 str1 初始化为空值,因为在这种特定情况下您不必担心空值终止。

于 2012-09-20T18:17:40.257 回答
1

您已经告诉它复制 strlen(str2) 字符数,这恰好是字符串的长度(空索引)。

它与使用 strcpy() 相同。它想说的是,如果您需要复制 NULL,您可以使用 memcpy,因为 strcpy() 将在它找到的第一个 null 处停止。

于 2012-09-20T18:19:11.863 回答
0

用大于str1的字符串初始化并再试一次,你会看到它是如何不复制空值的。你只是幸运的是零填充。我更改了代码以显示输出对内容的依赖性: str2str1str1

#include <stdio.h>
#include <string.h>

int main()
{
    char str1[20] = "xxxxxxxxxxxxxxxxxxx";
    char str2[20] = "Another Text---";

    memcpy(str1, str2, strlen(str2));
    printf("%s\n%s", str1, str2);

    return 0;
}

输出将是:

Another Text---xxxx
Another Text---
于 2012-09-20T18:27:54.800 回答