6
#inlcude <stdio.h>
#inlcude <stdlib.h>
#inlcude <string.h>

int main() {
    char *buff = (char*)malloc(sizeof(char) * 5);
    char *str = "abcdefghijklmnopqrstuvwxyz";

    memcpy (buff, str, strlen(str));

    while(*buff) {
        printf("%c" , *buff++);
    }

    printf("\n");

    return 0;
}

このコードは、文字列「abc...xyz」全体を出力します。しかし、「buff」にはその文字列を保持するのに十分なメモリがありません。memcpy() はどのように機能しますか? realloc() を使用しますか?

4

4 に答える 4

12

コードの動作は未定義です。あなたの質問に答えるために、いいえmemcpyは使用しませんreallocsizeof(buf)収容するのに十分なはずstrlen(str)です。それ以下のものはクラッシュです。

小さなプログラムであるため出力が出力される場合がありますが、実際の大きなコードでは、デバッグエラーが発生します。コードを次のように変更します。

const char* const str = "abcdefghijklmnopqrstuvwxyz";
char* const buff = (char*)malloc(strlen(str) + 1);

*buff++また、メモリレコード(割り当てたもの)が失われるため、実行しないでください。メモリ使用量が終わっmalloc()たら実行する必要がありますfree(buff)。そうしないと、メモリリークになります。

于 2011-05-23T04:45:49.003 に答える
9

文字列全体が出力されている可能性がありますが、これは安全ではなく、未割り当てのメモリに対して読み書きを行っています。これにより、未定義の動作が発生します。

memcpyメモリ割り当ては行いません。指定した場所から読み書きするだけです。そうしても問題ないかどうかはチェックしません。この場合、プログラムがクラッシュしなければ幸運です。

于 2011-05-23T04:42:15.293 に答える
1

memcpy()はどのように機能しますか?

未定義動作を呼び出したためです。未定義の動作は期待どおりに機能する可能性があり、まったく異なる動作をする可能性があります。同じプログラムの異なる実行間でも異なる場合があります。また、ハードディスクをフォーマットしても、標準に準拠している可能性があります(もちろん、そうなる可能性は低いですが:P)

未定義の動作とは、動作が文字通り何もするように定義されていないことを意味します。あなたが見ている振る舞いを含め、何でも有効です。freeそのメモリを使用しようとすると、ターゲットプラットフォームのCランタイムがおそらく文句を言うことに注意してください。;)

于 2011-05-23T04:45:52.533 に答える
1

いいえmemcpyは使用しませんmalloc。ご想像のとおり、 の終わりを書き留めていますbuff。あなたの単純な例では、それは明らかな害はありませんが、悪いことです。「実際の」プログラムで問題が発生する可能性のあるもののいくつかを次に示します。

  • buff後で微妙な (またはそれほど微妙ではない) バグにつながるメモリに割り当てられた何かに走り書きをするかもしれません。
  • mallocおよびによって内部的に使用されるヘッダーに走り書きをするとfree、それらの関数を次に呼び出すときにクラッシュやその他の問題が発生する可能性があります。
  • プロセスに割り当てられていないアドレスに書き込んでしまう可能性があります。その場合、プログラムはすぐにクラッシュします。(これはあなたが期待していたものだと思います。)

mallocこのような場合に (通常は) プログラムをクラッシュさせるために、割り当てられたメモリの周りにマップされていないガード ページを配置する実装があります。他の実装はこれを検出しますが、次のmallocorのfree呼び出し時 (またはヒープをチェックする特別な関数を呼び出したとき) にのみ検出されます。

于 2011-05-23T04:50:23.557 に答える