根据 C 标准,什么是字符串重叠?

What is string overlapping according to the C Standard?

来自 C 标准:

7.21.2.4 The strncpy function

If copying takes place between objects that overlap, the behavior is undefined.


什么是重叠?

很明显,当目标字符串的开头与源字符串的结尾交叉时,它是重叠的。

但是在下一个例子中是否发生了重叠?

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 只是像 this implementation 中那样逐字符复制符号,应该没有问题。

strncpy 不必以任何特定方式实施。 C 标准只规定了它应该遵循的 API 契约。任何 特定的 实现都可以选择使重叠成为 non-issue,但标准并未强制这样做。

strncpy 可以根据 memcpy 来实现,当源和目标重叠时会出现未定义的行为。不过按照上面说的规格,完全没问题。

If strncpy just copyes symbols char by char like it is in this implementation, there should be no problem.

这正是问题所在。 该标准没有指定函数必须以哪种方式运行,但应该给出什么输出,同时指定如果存在任何类型的重叠,则结果为 UB程序员可以自由使用他们喜欢的任何方法。

这是因为新的指令或处理器架构可以支持使用新的和更高效的指令,这些指令可以遵循不同的寻址方式(即以相反顺序或混合顺序复制)。这可能会给您任何不可预测的结果,实际上是 未定义的行为

最终您可以使用 memmove 明确允许重叠的函数,或者编写您自己的重叠感知函数。