我有一个关于使用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;
}
Run Code Online (Sandbox Code Playgroud)
此序列\r从输入字符串中删除每个(回车).我知道(来自Kernigham和Ritchie)strcpy的一个非常简单的实现如下
while (*t++=*s++) ;
Run Code Online (Sandbox Code Playgroud)
现在我使用gcc(Gentoo 4.5.4 p1.0,pie-0.4.7)4.5.4编译我的程序,它打印出来:
abcdefghi
jklmnpqr <-- missing 'o'
stuvwxxyz <-- doubled 'x'
Run Code Online (Sandbox Code Playgroud)
我想这个编译器(实际上它的库)使用了非常复杂的序列strcpy,我不明白其中的原因.
Jon*_*pan 13
你被警告不要这样做.原因是逐字节复制实际上非常慢并且需要大量循环才能通过字符串.编译器可以轻松地优化它(例如,通过一次复制一个int大小的块,或者使用一些特定于平台的并行化.)
但是如果字符串重叠,那么这些优化会对您的数据做出不再有效的假设.结果,他们给你未指定的结果.很可能你的旧GCC根本没有做任何这样的优化.
由于文档strcpy()说不使用重叠字符串,所以不要.
弄清楚你的实现正在做什么的最好方法当然是阅读其库的源代码。
如果源代码不可用,下一个最佳选择可能是读取编译器生成的汇编代码。
您还可以查看该库的“严肃”开源实现,也许可以从中得出一些结论。
一个想法可能是库一次复制的数据块比一个字符更大,当您违反设计假设时,就会中断。