C语言中memcpy、memmove、strncpy的差异及正确选型
C语言中memcpy、memmove、strncpy的差异与正确选择
在C语言中复制数据时,memcpy、memmove、strncpy的调用形式相似,但运行结果存在明显差异。不少开发者指出部分函数存在使用风险,下面结合测试代码和结果明确三者的差异及正确选择。
测试代码
#include <stdio.h> #include <string.h> int main() { char src[19] = "abcdef"; char *target = src; memcpy(target+3, target, 5); printf("from memcpy : %s\n", target); strncpy(target+3, target, 5); printf("from strncpy : %s\n", target); memmove(target+3, target, 5); printf("from memmove : %s\n", target); }
运行结果
from memcpy : abcabcde from strncpy : abcabcab from memmove : abcabcab
函数差异分析
memcpy
- 核心特性:仅完成内存字节复制,不处理内存重叠场景。当源与目标内存区域重叠时,复制结果属于未定义行为(不同编译器、平台可能输出不同结果)。
- 适用场景:能确保源和目标内存无重叠的通用内存复制,效率较高。
strncpy
- 设计定位:用于固定长度的字符串复制,而非通用内存复制。
- 风险点:
- 若源字符串长度小于指定复制长度,会自动补
\0至指定长度,可能浪费内存; - 若源字符串长度大于等于指定复制长度,不会自动添加字符串终止符
\0,易导致后续字符串操作越界; - 处理内存重叠时行为未定义,测试结果的差异正是源于此。
- 若源字符串长度小于指定复制长度,会自动补
- 现状:虽未被标准C废弃,但因安全隐患,推荐使用
strncpy_s(安全扩展)或strlcpy(非标准但更安全)替代。
memmove
- 核心特性:专门针对内存重叠场景设计,内部会判断源与目标的地址关系,选择从高地址到低地址或低到高的复制顺序,确保复制结果正确。
- 适用场景:所有内存复制场景,尤其是无法确定内存是否重叠时,是最安全的选择。
结论
- 确定内存无重叠:优先用
memcpy(效率最优); - 内存可能重叠或不确定:必须用
memmove(安全可靠); - 避免用
strncpy做通用内存复制,字符串复制场景优先考虑更安全的替代函数。
内容的提问来源于stack exchange,提问作者Bishop
相关产品推荐
相关产品推荐

