来自C标准:
<小时 />7.21.2.4 结构函数
如果在重叠的对象之间进行复制,则行为是未定义的。
什么是重叠?
很明显,当目标字符串的开头与源字符串的结尾交叉时,它是重叠的。
但是在下一个示例中是否发生了重叠?
const char* dateConst = "2017-01-25";
char* date = malloc(16);
strcpy(date, dateConst);
strncpy(date+4, date+5, 2);
strncpy(date+6, date+8, 3);
printf("%sn", date);
输出:20170125
如果 strncpy 只是像在这个实现中那样逐个复制符号字符,应该没有问题。
如果 strncpy 只是像这样逐个复制符号字符 执行,应该没有问题。
这正是问题所在。该标准没有指定函数必须以哪种方式运行,而是指定应该提供什么输出,同时指定如果存在任何类型的重叠,结果是 UB 使编码人员可以自由使用他们喜欢的任何方法。
这是因为新的指令或处理器架构可以赞助使用新的和更有效的指令,这些指令可以遵循不同的寻址方式(即以相反顺序或混合顺序复制)。这可能会给你任何不可预测的结果,实际上是一个未定义的行为。
最终,您可以使用显式允许重叠memmove
函数,或者编写自己的重叠感知函数。
strncpy
不必以任何特定方式实现。C 标准只规定了它应该遵循的 API 协定。任何特定的实现都可以选择使重叠成为非问题,但标准不会强制这样做。
strncpy
可以在memcpy
方面实现,当源和目标重叠时,它受到未定义行为的影响。但是有了上面提到的规范,这是完全可以的。