如何实现strcpy?

时间:2012-10-17 13:25:26

标签: c strcpy

我有一个关于使用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使用了非常复杂的序列,我不明白原因。

2 个答案:

答案 0 :(得分:13)

你被警告不要这样做。原因是逐字节复制实际上非常慢并且需要大量循环才能通过字符串。编译器可以轻松地优化它(例如,通过一次复制int大小的块,或使用某些特定于平台的并行化。)

但是如果字符串重叠,那么这些优化会对您的数据做出不再有效的假设。结果,他们给你未指定的结果。很可能你的旧GCC根本没有做过任何这样的优化。

由于strcpy()的文档说不使用重叠字符串,

答案 1 :(得分:2)

了解您的实现正在做什么的最好方法当然是阅读其库的来源。

如果源不可用,则下一个最佳选择可能是读取编译器生成的生成的汇编代码。

您还可以查看该库的“严肃”开源实现,并从中得出一些结论。

Onea的想法可能是图书馆一次以比一个角色更大的数据块复制数据,当你违反设计假设时,它会中断。