根据 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
明确允许重叠的函数,或者编写您自己的重叠感知函数。
来自 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
明确允许重叠的函数,或者编写您自己的重叠感知函数。