来自C标准:
7.21.2.4 strncpy函数
如果在重叠的对象之间进行复制,则行为未定义。
什么是重叠?
很明显,当目标字符串的开头越过源字符串的结尾时它会重叠。
但在下一个例子中是否会发生重叠?
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("%s\n", date);
输出:20170125
如果strncpy只是像char this implementation那样复制符号char,那么应该没问题。
答案 0 :(得分:1)
strncpy
不必以任何特定方式实施。 C标准仅规定了它应遵循的API合同。任何特定的实现都可以选择使重叠成为非问题,但标准不会强制这样做。
strncpy
可以用memcpy
来实现,当源和目标重叠时,它会受到未定义的行为的影响。但是根据上面提到的规范,它完全没问题。
答案 1 :(得分:1)
如果strncpy只是像char那样复制符号char 实施,应该没有问题。
这正是问题所在。 标准没有指定函数必须以哪种方式运行,但是应该给出什么输出,同时指定如果存在任何类型的重叠,结果是 UB 使编码器可以自由使用使用他们喜欢的任何方法。
这是因为新的指令或处理器体系结构可以赞助使用可以遵循不同寻址方式的新的和更有效的指令(即,以相反的顺序或以混合的顺序复制)。这可以为您提供无法预测的结果,实际上是未定义的行为。
最终,您可以使用明确允许重叠的memmove
函数,或者编写您自己的重叠感知函数。