3

cplusplus.comから: 「この関数はmemcpy、ソース内の終端の null 文字をチェックしません。常に正確に num バイトをコピーします。」

したがって、次のコードは実行時エラーになるはずですよね?

char str1[20] = "";
char str2[20] = "Another Text---";

memcpy(str1, str2, strlen(str2));
printf("%s\n%s", str1, str2);

しかし、gcc コンパイラを使用すると、このコードから常に正しい出力が得られます。これは、memcpy が実際に最後からヌル文字をコピーすることを意味しますか、str2それとも単なるランダムなケースですか?

編集:すべての NULL 文字で文字列を初期化するstr1[20] = "A"いくつかの回答が指摘しているため、 で同じ動作が得られます。str1[20] = ""

4

4 に答える 4

15

パズルの鍵となる要素は initializer""です。これは以下と同じです:

char str1[20] = { 0 };

これは次と同じです (少なくとも GCC では、常に C++ では):

char str1[20] = { };

また

char str1[20] = { 0, 0, 0, ..., 0 };   // 20 times

これらの初期化子はすべて、20 個のゼロを保持するように配列を初期化します。

memcpy呼び出しはnull ターミネータをコピーしません (カウントstrlenないため) が、宛先配列は最初から適切にゼロ設定されているため、すべて問題ありません。

于 2012-09-20T18:20:40.637 に答える
1

memcpy は、str2 から str1 に strlen(str2) バイトをコピーしています (ただし、これは null バイトがコピーされるという意味ではありません)。その多くのバイトに対して str1 に十分なスペースがあるため、機能します。memcpy は、メモリを正確にコピーします。

20 を超えるものを一方から他方にコピーしようとすると、エラーが発生します。どちらの変数にも 19 文字を超えて格納しないでください。

kerrek が説明したように、この特定のケースでは null 終了について心配する必要がないため、str1 を null に初期化するのにも役立ちます。

于 2012-09-20T18:17:40.257 に答える
1

strlen(str2) 文字数をコピーするように指示しましたが、これはたまたま文字列の長さ (null インデックス) です。

strcpy() を使用するのと同じです。つまり、 NULL をコピーする必要がある場合は、strcpy() が見つかった最初の null で停止するため、memcpy を使用できます。

于 2012-09-20T18:19:11.863 に答える
0

より大きいstr1文字列で を初期化し、もう一度試してみると、null がコピーされないことがわかります。ゼロで埋められたのは幸運でした。出力のコンテンツへの依存関係を示すようにコードを変更しました: str2str1str1

#include <stdio.h>
#include <string.h>

int main()
{
    char str1[20] = "xxxxxxxxxxxxxxxxxxx";
    char str2[20] = "Another Text---";

    memcpy(str1, str2, strlen(str2));
    printf("%s\n%s", str1, str2);

    return 0;
}

出力は次のようになります。

Another Text---xxxx
Another Text---
于 2012-09-20T18:27:54.800 に答える