一文看懂内存拷贝神器:memcpy() 函数详解】
在 C 语言的编程世界里,我们经常需要和内存打交道。如果你需要把一块内存里的数据“原封不动”地搬运到另一块内存中,那么标准库提供的 memcpy 函数绝对是你的得力助手。
今天我们就来掰开揉碎地讲讲这个函数,看看它怎么用,以及有哪些需要避开的坑。
1. 认识 memcpy:它是做什么的?
memcpy 的全称是 memory copy(内存拷贝)。它的核心功能非常简单直接:从源内存地址的起始位置开始,拷贝 n 个字节的数据到目标内存地址中。
不管你内存里存的是字符串、整型数组还是复杂的结构体,在 memcpy 眼里,它们都只是一串毫无感情的二进制字节流。它只负责搬运,绝不夹带私货。
2. 函数原型与参数解析
要使用 memcpy,首先需要引入头文件:
#include <string.h>
它的函数原型长这样:
void *memcpy(void *dest, const void *src, size_t n);
我们来逐一拆解这些参数:
-
dest(Destination):目标指针。指向你想要把数据存放进去的那块内存。 -
src(Source):源指针。指向你想要读取数据的哪块内存。注意前面有个const,说明它不会修改源数据。 -
n:你要拷贝的字节数(注意,是字节数,不是元素个数!这是新手常犯的错误)。 -
返回值:函数会返回一个指向目标内存区域
dest的指针。
3. 代码实战:memcpy 怎么用?
光说不练假把式,我们来看看实际代码中怎么用。
场景一:拷贝字符串
虽然拷贝字符串通常用 strcpy,但 memcpy 同样可以胜任,只要你指定好长度即可。
#include <stdio.h>
#include <string.h>
int main() {
const char src[50] = "Hello, C Programming!";
char dest[50];
// 把 src 中的字符串(包含末尾的 '\0')拷贝到 dest 中
// +1 是为了把隐藏的字符串结束符 '\0' 也拷过去
memcpy(dest, src, strlen(src) + 1);
printf("目标字符串 dest = %s\n", dest);
return 0;
}
场景二:拷贝整型数组(重点)
这是 memcpy 最大显身手的地方。当你需要复制一个非字符数组时,strcpy 就无能为力了。
#include <stdio.h>
#include <string.h>
int main() {
int src_array[] = {10, 20, 30, 40, 50};
int dest_array[5];
// 注意第三个参数:必须是 (元素个数 * 单个元素所占的字节数)
memcpy(dest_array, src_array, 5 * sizeof(int));
printf("拷贝后的 dest_array: ");
for(int i = 0; i < 5; i++) {
printf("%d ", dest_array[i]);
}
printf("\n");
return 0;
}
4. 🚨 避坑指南:致命的“内存重叠”
memcpy 虽然高效,但它是个“愣头青”——它在拷贝时,不会检查源内存和目标内存是否发生重叠(Overlap)。
什么是内存重叠?假设你有一个数组,你想把前 5 个元素拷贝到从第 3 个元素开始的位置上。这时候源区域和目标区域就重叠了。如果你在这种情况下使用 memcpy,它的行为是未定义的(Undefined Behavior)。可能会导致数据在被读取前就被覆盖,拷出一堆乱码。
终极建议:
-
如果你明确知道源内存和目标内存绝不可能重叠,放心大胆地使用
memcpy,它的效率非常高。 -
如果你怀疑两块内存有可能重叠,请乖乖换成它的兄弟函数:
memmove()。memmove会在拷贝前处理好重叠问题,保证数据安全,代价是稍微牺牲一点点性能。
总结
-
memcpy用于拷贝任意类型的数据。 -
按**字节(byte)**进行拷贝,计算长度时别忘了乘上
sizeof(数据类型)。 -
需要包含
<string.h>。 -
严禁用于有内存重叠的场景,重叠场景请找
memmove。
更多推荐



所有评论(0)