strcpy 与 memcpy 的区别和容易踩的坑
2026/7/3 13:58:34 网站建设 项目流程

strcpy 与 memcpy 的区别。

考点:字符串复制与内存复制之间的区别。
出现频率:★★★★

解析

strcpy 和 memcpy 主要有以下 3 方面的区别。

- 复制的内容不同。strcpy 只能复制字符串,而 memcpy 可以复制任意内容:字符数组、整型、结构体、类等。

- 复制的方法不同。strcpy 不需要指定长度,它遇到字符串结束符 '\0' 便结束;memcpy 则是根据其第3个参数决定复制的长度。

- 用途不同。通常在复制字符串时用 strcpy,而需要复制其他类型数据时则用 memcpy。

先记住核心区别:strcpy按 **'\0' 终止 **;memcpy只按指定字节 size拷贝,完全不识别字符串结束符。

坑 1:忘记手动拷贝字符串结束符\0(最高频错误)

字符串合法的前提是末尾有\0,memcpy 不会自动补。

错误示例

char src[] = "abc123"; char dest[10]; // sizeof(src) 包含末尾'\0'没问题,但很多人写成 strlen(src) memcpy(dest, src, strlen(src)); printf(dest); // 乱码,无结束符,越界读取内存

原因:strlen("abc123")= 6,只复制 6 个有效字符,漏掉第 7 字节\0

正确两种写法

  1. 带终止符拷贝
memcpy(dest, src, strlen(src) + 1);
  1. 直接用 sizeof(数组)

c

运行

memcpy(dest, src, sizeof(src));

坑 2:目标缓冲区过小,内存越界覆盖(缓冲区溢出)

char src[] = "HelloWorld123456"; char dest[5]; // 只能存4字符+结束符 memcpy(dest, src, strlen(src)+1); // 严重越界,覆盖栈上其他变量,崩溃/数据错乱

规避:拷贝前校验strlen(src)+1 <= sizeof(dest)

坑 3:源和目标内存重叠,memcpy 未做重叠处理(行为未定义)

memcpy 标准不保证重叠安全,重叠场景要用 memmove。

错误示例

char buf[] = "123456789"; // 目标在源区间内部,重叠 memcpy(buf + 2, buf, 5); // 预期:12123456789,实际数据被提前覆盖,结果错乱

解决:内存存在重叠一律改用memmove

坑 4:size 传错,混淆字节数与字符个数(宽字符尤其致命)

窄 char 场景易错点

char src[] = "abcd"; memcpy(dest, src, 4); // 丢'\0'

wchar_t 宽字符串大坑(极易踩)

wchar_t 一个字符占 2/4 字节,不能直接用 strlen 算长度传给 memcpy:

c

运行

wchar_t wsrc[] = L"test"; // 错误:wcslen得到字符数,不是字节数 memcpy(wdest, wsrc, wcslen(wsrc)); // 正确:字节数 = 字符数 * sizeof(wchar_t) memcpy(wdest, wsrc, (wcslen(wsrc)+1)*sizeof(wchar_t));

坑 5:空指针传入 memcpy,直接程序崩溃

char *src = NULL; char dest[20]; memcpy(dest, src, 5); // 解引用空指针,段错误

规避:拷贝前判空指针。

坑 6:const 与指针类型不匹配编译警告 / 截断

源字符串是const char*,传给 memcpy 第二个参数没问题; 但如果强转、混用无符号 /char 指针,部分编译器会告警,极端平台截断高位字节。

坑 7:栈局部字符串拷贝后未初始化残留干扰

目标数组只拷贝前 N 字节,后面内存是随机脏数据,若忘记\0,打印会读到残留垃圾。

char dest[16] = {0}; // 初始化为0最稳妥

坑 8:混用 memcpy /strcpy 逻辑,思维惯性出错

  • strcpy:自动读到\0停止,不用管长度
  • memcpy:必须精确提供总字节(含\0) 很多人写惯 strcpy,用 memcpy 时下意识只传有效字符长度,必出乱码。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询