You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何memcpy传入数组buff和&buff的执行效果完全相同?

为什么memcpy(buff, msg, sizeof(msg))和memcpy(&buff, msg, sizeof(msg))执行效果一致?

问题背景

给定以下代码:

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

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

// 或者
memcpy(&buff, msg, sizeof(msg));

这两行memcpy的执行效果完全一致,但按照常规理解,&buff似乎应该是取数组的地址,会把数据复制到存储数组地址的指针位置,而非数组本身的内存。比如用户设想的内存布局:

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

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

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

用户无法理解为什么msg没有被写入0x5000地址覆盖0x1000。

核心原因:数组名的特殊性

你混淆了数组名和指针变量的本质区别:

  • buff是数组名,它不是一个存储数组地址的指针变量,而是直接代表整个数组的内存块。在大多数表达式中(比如作为函数参数时),数组名会隐式转换为指向数组第一个元素的指针(即&buff[0]),但它本身不是指针变量,没有单独的内存存储它的地址。
  • &buff是取整个数组的地址,它的类型是char (*)[100](指向100个char的数组的指针),但这个地址的数值和数组第一个元素的地址&buff[0]完全相同——因为整个数组的起始位置就是第一个元素的位置。

为什么memcpy行为一致?

memcpy的第一个参数类型是void*,不管传入的是buff(转换为char*,指向buff[0])还是&buff(转换为void*,指向整个数组的起始地址),它们的地址数值完全相同。所以memcpy都会从这个相同的起始地址开始复制sizeof(msg)字节的数据,最终效果自然一致。

纠正你的内存布局误解

你设想的0x5000位置的指针变量根本不存在——buff是数组,它直接占用从0x1000开始的100字节内存,没有额外的内存存储“数组的地址”。只有当你显式定义一个指针变量时,比如:

char* p = buff;

这时候p才是一个指针变量,它会占用一块内存(比如0x5000)来存储buff的起始地址0x1000,此时&p才是这个指针变量的地址。

内容的提问来源于stack exchange,提问作者RemyBean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:44:55