【发布时间】:2012-10-07 18:33:20
【问题描述】:
我有一个关于使用 strcpy 的问题。我知道 ANSI C 标准说:源和目标不能重叠,否则行为是不可预测的。如果在 Linux 下使用旧的 gnu C 编译器编译,我将向您展示一段代码,它可以按我的预期工作。
#include <string.h>
#include <stdio.h>
char S[80],*P;
int main() {
strcpy(S,"abcdefghi\r\njklmnopqr\r\nstuvwxyz\r\n");
for (P=S; P=strchr(P,'\r'); P++) strcpy(P,P+1);
printf("%s\n",S);
return 0;
}
这个序列从输入字符串中删除每个\r(回车)。我知道(来自 Kernigham 和 Ritchie)strcpy 的一个非常简单的实现如下
while (*t++=*s++) ;
现在我使用 gcc (Gentoo 4.5.4 p1.0, pie-0.4.7) 4.5.4 编译了我的程序,它打印了这个:
abcdefghi
jklmnpqr <-- missing 'o'
stuvwxxyz <-- doubled 'x'
我想这个编译器(实际上是它的库)对strcpy 使用了一个非常复杂的序列,我不明白其中的原因。
【问题讨论】:
-
嘿,@jsalonen 比我更容易编辑
-
您可以通过在系统中找到 .asm 文件来查看实现。
-
它可能使用了复制更大(多字节)块的优化。一种常见的技术是将指针转换为最长的可用整数单元(如
long long *)并复制它。这意味着副本会覆盖正在复制的内容。 -
奇怪的结果是 abcdefghi 然后 jklmnpqr 然后 stuvwxxyz 。第二行 o 缺失,第三行 x 加倍。
-
我使用 gdb(gnu 调试器)查看了 S:每个 '\r' 都被删除并且 S 是 "abcdefghi\njklmnpqr\nstuvwxxyz\n"