使用 memcpy 将数据复制到数组中

Posted

技术标签:

【中文标题】使用 memcpy 将数据复制到数组中【英文标题】:copying datas into the array using memcpy 【发布时间】:2012-07-13 02:19:56 【问题描述】:
#include <stdio.h>

int main()
    int a[4];
    int b[4],i;
    a[0] = 4;
    a[1] = 3;
    a[2] = 2;
    a[3] = 1;
    memcpy(&b, &a, sizeof(a));
    for (i = 0; i < 4; i++)
        printf("b[%d]:%d",i,b[i]);
    
    printf("%d",sizeof(b));

回答:

b[0]:4b[1]:3b[2]:2b[3]:116
Exited: ExitFailure 2

我得到了正确的答案。但是在退出时出现异常:ExitFailure 2.

这种使用memcpy复制数组数据的方式不对吗?

【问题讨论】:

尝试在末尾添加return 0; 您在这里使用memcpy 有点错误,您不需要地址运算符(&amp;),因为类型数组与类型指针兼容,所以memcpy(b, a, sizeof(a)); 就够了。 你是对的。我在 codepad.org 中执行。所以我没有收到缺少返回值的错误消息。 但是使用 & 作为数组类型也会给我一个数组的地址。 &amp; 对于数组是可选的。我总是把它放在一边。但是对于指针,显然是不同的。 【参考方案1】:

尝试在main() 末尾添加return 0;

省略返回值可能会导致函数返回堆栈垃圾。 (那不是 0)

因此,测试应用/脚本在看到非零返回值时会抱怨失败。


在 C99 之前,省略 return 语句在技术上是未定义的行为。从C99开始,如果省略则默认为0

更多详情:Why main does not return 0 here?

【讨论】:

可能不是栈垃圾,而是最后一个printf的返回值,也就是2。 是的,假设相同的寄存器/堆栈位置保存printf() 的剩余返回值。它将在 x86 和 x64 上。【参考方案2】:

更正:

未显式返回 0 (return 0;) 会导致 undefined behaviour 先于 C99

但是,由于特定寄存器通常用于存储函数的返回值(例如 x86 中的 eax),因此会返回该寄存器中的值。

恰好printf("%d",sizeof(b));char 数组的大小存储在用于从函数返回值的同一寄存器中。

因此,返回值为2

原答案:

由于您没有在 main 末尾声明 return 0;,因此最后一次 printf 调用被解释为 main 的返回值。

sizeof(b) 返回16,即2 字符长,因此程序返回2 作为退出代码。

【讨论】:

这是不正确的。在这种情况下,返回代码未定义。但在大多数情况下,返回值存储在寄存器中。所以退出 main 保留 printf 的返回值(寄存器)的旧值。 您的意思是 printf 值偶然存储在 %rax 中(例如在 x86 上),这就是为什么它在这种情况下返回 2【参考方案3】:

你的 memcpy 语句有问题。

1) 您应该将指针传递给您的数组,而不是将指针传递给 你的数组。

2) 你应该传递数组的大小,sizeof(a) 将只返回 int 的大小,所以你必须 将它与数组的最大索引相乘。

您只需对代码进行少量修改,如下所示,

memcpy(b, a, sizeof(a) * 4);

【讨论】:

以上是关于使用 memcpy 将数据复制到数组中的主要内容,如果未能解决你的问题,请参考以下文章

memcpy问题,如图,memcpy下一个复制的数据会覆盖掉原有数据,有没有啥方法可以把新的数据加到原有数据

memcpy和strcpy的区别

memcpy和strcpy的区别

memcpy 是可简单复制的类型构造还是赋值?

C语言中的复制函数(strcpy和memcpy)

内存操作函数memmove,memcpy,memset