web-dev-qa-db-ja.com

strcpy vs. memcpy

memcpy()strcpy()の違いは何ですか?私はプログラムの助けを借りてそれを見つけようとしましたが、どちらも同じ出力を提供しています。

int main()
{
    char s[5]={'s','a','\0','c','h'};
    char p[5];
    char t[5];
    strcpy(p,s);
    memcpy(t,s,5);
    printf("sachin p is [%s], t is [%s]",p,t);
    return 0;
}

出力

sachin p is [sa], t is [sa]
68

この効果を見るためにできること

このコードをコンパイルして実行します。

_void dump5(char *str);

int main()
{
    char s[5]={'s','a','\0','c','h'};

    char membuff[5]; 
    char strbuff[5];
    memset(membuff, 0, 5); // init both buffers to nulls
    memset(strbuff, 0, 5);

    strcpy(strbuff,s);
    memcpy(membuff,s,5);

    dump5(membuff); // show what happened
    dump5(strbuff);

    return 0;
}

void dump5(char *str)
{
    char *p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%2.2x ", *p);
        ++p;
    }

    printf("\t");

    p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%c", *p ? *p : ' ');
        ++p;
    }

    printf("\n", str);
}
_

次の出力が生成されます。

_73 61 00 63 68  sa ch
73 61 00 00 00  sa
_

「ch」がmemcpy()によってコピーされたが、strcpy()ではコピーされなかったことがわかります。

112
egrunin

strcpyは、NUL('\0')文字を検出すると停止しますが、memcpyは検出しません。 printfの%sもNULで停止するため、ここでは効果は見られません。

68
Yann Ramin

strcpyは、ソース文字列のヌルターミネータが見つかると終了します。 memcpyには、サイズパラメータを渡す必要があります。両方の文字配列でヌルターミネータが見つかった後、printfステートメントが停止している場合は、t[3]およびt[4]もデータをコピーしました。

12
fbrereto

strcpyは、ソースでNULLまたは '\ 0'文字が見つかるまで、ソースから宛先に文字を1つずつコピーします。

while((*dst++) = (*src++));

as memcpyは、ソースのデータに関係なく、指定されたサイズnのソースから宛先にデータ(文字ではない)をコピーします。

ソースに文字以外が含まれていることがわかっている場合は、memcpyを使用する必要があります。暗号化されたデータまたはバイナリデータの場合、memcpyが理想的な方法です。

strcpyは推奨されないため、strncpyを使用します。

9
Viswesn

s文字列にヌル文字があるため、printfはそれ以上何も表示しません。 ptの違いは、文字4と5になります。pには何もありません(ゴミになります)。tには'c''h'があります。

3

主な違いは、memcpy()は常に指定した正確なバイト数をコピーすることです。一方、strcpy()は、NUL(別名0)バイトを読み取るまでコピーし、その後停止します。

2
Jeremy Friesner
  • 動作の違い:strcpyまたは'\0'に遭遇すると、NULLは停止します
  • パフォーマンスの違い:memcpyは通常、コピーするデータを常にスキャンするstrcpyよりも効率的です。
2
euccas

テストプログラムの問題は、printf()がnull終了_%s_に遭遇すると、_\0_への引数の挿入を停止することです。そのため、出力では、memcpy()chの文字もコピーしたことに気付いていないでしょう。

GNU _glibc-2.24_)で、(x86の場合)strcpy()memcpy(dest, src, strlen(src) + 1)を呼び出すだけです。

0
Jaspar L.