1

したがって、たとえば「0123456789」のC文字列は、実際には11文字の配列を占有し、本体に10文字、終端のnullに1つあると理解しています。それが本当なら、以下のコードが何らかのエラーを引き起こさないのはなぜですか?

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

int main(int argc, char ** argv){

    char * my_string = "0123456789";
    /* my string should occupy 11 bytes */

    int my_len = strlen(my_string);
    /* however, strlen should only return 10, 
        because it does not count the null byte */

    char * new_string = malloc(my_len);
    /* allocate memory 10 bytes wide */

    memcpy(new_string, my_string, my_len);
    /* copy the first 10 bytes from my_string to new_string
        new_string should NOT be null terminated if my understanding
        is correct? */

    printf("%s\n", new_string);

    /* Since new_stirng is NOT null terminated it seems like this should
        cause some sort of memory exception.
        WHY DOES THIS NOT CAUSE AN ERROR?

    */

    return 0;
}

null で終了していないため、他のアプリケーションのメモリに到達するか、ランダムに配置された 0x00 がクラッシュするか、何か奇妙なものを出力するまで、永遠に読み取るnew_stringことが期待されます。printfどうしたの?

4

5 に答える 5

4

未定義の動作を作成しました。動作はコンパイラとプラットフォームに依存します。クラッシュする可能性があります。それはうまくいくかもしれません。それはあなたを乾杯させることができます。コンピューターを特異点に崩壊させ、太陽系を吸収する可能性があります。

あなたの場合、のメモリnew_string[11]はすでにだった可能性があります。0これは'\0'、または終端のヌル文字です。

于 2012-06-01T20:48:45.053 に答える
3

あなたの場合、malloc から取得した特定のメモリ ブロックは (プログラムによって) 以前に使用されたことがなく、割り当て時に OS によっておそらくゼロ初期化されました。したがって、11 番目のバイトはゼロである可能性が高く、エラーではありません。実行時間の長いプログラムでは、malloc は 11 番目のバイトが 0 ではないダーティ チャンクのメモリを返す可能性があるため、printf ステートメントで問題が発生します。実際には、(最初の null が検出されるまで) ガベージを出力するか、割り当てられた領域の末尾に null がない場合は segfault を出力します。

(他の人が言ったように、動作は正式には定義されていません。私はあなたが見たことを説明しているだけです)。

于 2012-06-01T20:51:06.787 に答える
3

それは未定義の動作だからです。未定義の動作は、1 つの可能性ではありますが、セグ フォールトを意味するものではありません。

于 2012-06-01T20:46:47.613 に答える
1

またはどこかにランダムに配置された 0x00 ... 何か奇妙なものを出力します。

これは一般的に観察される動作です。実際に何が起こるかは未定義です。

于 2012-06-01T20:47:21.267 に答える
0

これは未定義の動作です。場合によっては、私が想像するメモリレイアウトに依存するクラッシュを引き起こす可能性があります

于 2012-06-01T20:51:01.160 に答える