1. 为什么C程序员必须掌握这四大内存函数
在C语言的世界里,内存操作就像外科医生手中的手术刀——精准、直接且危险。我至今记得初学C语言时,因为误用memcpy导致程序崩溃,花了整整两天才找到那个越界写入的bug。memcpy、memmove、memset和memcmp这四个函数构成了C语言内存操作的基石,它们直接操作内存字节的特性,既是其强大之处,也是新手最容易栽跟头的地方。
与strcpy等字符串函数不同,这些内存函数不关心数据类型,它们以字节为单位进行操作。这种设计带来了极高的灵活性:你可以用它复制结构体、清空数组、比较二进制数据。但代价是,编译器不会帮你检查类型安全,任何越界操作都会直接导致内存污染。根据2023年CVE漏洞数据库统计,约17%的内存安全漏洞与这些函数的不当使用有关。
关键区别:字符串函数遇到'\0'终止符就停止,而内存函数只认字节数和地址,就像蒙眼工作的搬运工,你必须明确告诉它起点、终点和搬运量。
2. memcpy:内存复制的利与弊
2.1 函数原型与基础用法
c复制void *memcpy(void *dest, const void *src, size_t n);
这个看似简单的函数隐藏着许多细节。dest是目标地址,src是源地址,n是要复制的字节数。返回值是dest本身,这种设计允许链式调用。但要注意:
- 地址必须非空(NULL检查是程序员的责任)
- 即使n=0,标准规定函数仍需返回dest
- 典型实现会针对不同CPU架构优化(如x86的REP MOVSB指令)
2.2 经典应用场景
- 结构体克隆:比逐个成员赋值更高效
c复制typedef struct { int id; char name[32]; } Person; Person p1 = {1, "Alice"}, p2; memcpy(&p2, &p1, sizeof(Person)); - 数组片段复制:
c复制int arr1[10] = {0}, arr2[5] = {1,2,3,4,5}; memcpy(arr1+3, arr2, 5*sizeof(int)); // 将arr2插入arr1的第3位
