memcpy是c标准库中按字节拷贝内存的函数,要求目标空间足够、源目标不重叠,适用于trivially copyable类型;错误用法包括传错地址或拷贝非平凡类型。

memcpy 给数组赋值的基本写法
能用,但必须确保目标数组有足够空间,且源和目标内存不重叠。直接 memcpy 是最常见做法,本质是按字节拷贝,不关心类型。
示例:把一个 int 数组复制到另一个同大小数组:
int src[3] = {1, 2, 3};
int dst[3];
memcpy(dst, src, sizeof(src));
注意:sizeof(src) 返回的是整个数组字节数(3 * sizeof(int)),不是指针大小,这点在栈上数组里才安全。
传参时容易踩的坑:别传错源或目标地址
常见错误是把数组名当成了指针却忽略了它退化后的含义,或者误传了单个元素地址。
- ✅ 正确:
memcpy(dst, src, sizeof(src))——src和dst都是数组名,自动转为首地址 - ❌ 错误:
memcpy(dst, &src, sizeof(src))——&src是指向数组的指针(类型int(*)[3]),地址虽相同但语义错,编译可能不报错但行为未定义 - ❌ 错误:
memcpy(dst, src + 1, sizeof(src))—— 源地址偏移了,但拷贝长度仍按原大小,越界读
用 memcpy 赋值结构体数组或自定义类型时要注意什么
只要类型是 trivially copyable(比如没有虚函数、非静态引用成员、用户定义拷贝构造等),就能安全 memcpy。C 风格结构体、POD 类型都符合。
示例:
struct Point { int x, y; };
Point src[2] = {{1,2}, {3,4}};
Point dst[2];
memcpy(dst, src, sizeof(dst));
⚠️ 如果结构体含 std::string、std::vector 等非 trivial 类型,memcpy 会位拷贝内部指针,造成双重析构或悬空指针 —— 这种情况必须用赋值运算符或 std::copy。
替代方案:什么时候不该用 memcpy
不是所有“赋值”场景都适合 memcpy。它绕过构造/析构,也不做类型检查。
- 目标是动态分配数组(如
new int[5])?可以,但记得用sizeof(int) * n算长度,别用sizeof(ptr) - 要部分拷贝或带偏移?确认长度参数准确,宁可显式写
n * sizeof(T),别依赖sizeof数组名(传入函数后数组名就退化成指针) - 只是初始化新数组?考虑
std::array或std::vector的构造/赋值,更安全;若追求极致性能且确定类型 trivial,再选 memcpy
真正难的不是调用 memcpy,而是判断「这个类型能不能 memcpy」和「这段内存边界有没有被悄悄改写」——这两点出问题时,往往连崩溃点都难以复现。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











