假设我有以下代码:

char buff[100] = {0};
char msg[] = "hello!";

memcpy(buff, msg, sizeof(msg));

OR

memcpy(&buff, msg, sizeof(msg));

为什么这两条Memcpy行的工作方式完全相同?

我预期当buff被使用时,它会将msg复制到buff衰减到的指针本身存储的内存中,而不是指针实际指向的内存中.

当我想象这些指针是这样的:

&buff->buff->buff[0]

我可以解释为什么他们的行为是一样的.但当我想象实际的记忆是这样的:

address        | value   | (name)
--------------  --------- ----------------
0x1000         | 'h'     | (buff[0])
0x1001         | 'e'     | (buff[1])
... etc
__________________________________________

0x5000-0x5008  | 0x1000  | (buf - char *)
__________________________________________

0x8000-0x8008  | 0x5000  | (&buf - char**)
__________________________________________

现在,我不明白为什么不将消息写入地址0x5000,而是覆盖值0x1000.

推荐答案

C 2018 6.3.2.1 3表示数组被转换为指向其第一个元素的指针,但以下情况除外:

  • 它是sizeof的操作数,
  • 它是一元&的操作数,或
  • 它是用于初始化数组的字符串.

因此,在memcpy(&buff, msg, sizeof(msg))中,buff是一元&的操作数,不会转换为指针.&buff提供指向数组的指针.

memcpy(buff, msg, sizeof(msg))中,buff被转换为指向其第一个元素的指针.

第一个元素的起始位置和数组的起始位置相同.因此,&buffbuff具有相同的值,但类型不同.因此,在两次调用中,数据都被复制到相同的位置.

(还要注意,类型的差异变得无关紧要,因为memcpy的第一个参数被声明为void * restrict,所以&buffbuff在调用之前都被转换为相同的类型.

C++相关问答推荐

为什么海湾合作委员会在共享对象中的. init_data的虚拟内存地址之前留出一个空白

%p与char* 等组合缺少的GCC Wform警告

为什么下面的递归基本情况在C中不起作用?

需要大整数和浮点数.使用long long int和long double

C中是否有语法可以直接初始化一个常量文本常量数组的 struct 成员?

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

如何在C中从函数返回指向数组的指针?

为什么在函数内部分配内存空间时需要添加符号?

在基本OpenGL纹理四边形中的一个三角形中进行渲染

在C++中访问双指针

防止规范模式在C++中 echo 特殊字符

每次除以或乘以整数都会得到0.0000

如何在POSIX-UEFI中获得输入?

这个空指针类型的转换是有效代码还是恶意代码?

我在C中运行和调试时得到了不同的输出

初始成员、公共初始序列、匿名联合和严格别名如何在C中交互?

在C中使用无符号整数模拟有符号整数

程序对大输入给出错误答案

&stdbool.h&q;在嵌入式系统中的使用

Malloc和对齐