1

c文字列に10バイトを割り当てようとしましたが、何も割り当てずに印刷しました。そして、cstringのサイズで印刷しました。しかし、結果は私が思っていたものとはかなり異なっていました。mallocはrawメモリのみを割り当てるので、ジャンク値を出力すると思いました。そして、c文字列のサイズを超えて印刷しようとしたので、動作は未定義である必要があると思いました。しかし、それらはすべてヌル文字を出力しました。これが私のコードだと思います。

int main(void)
{
    int i;
    char * c = (char *)malloc(10);
    for(i=0; i<20; ++i)
    {
        printf("%c.\n", *(c+i));
    }
    return 0;
}

そして、私は「。」の20行を見ました。誰かがこれを説明できますか?私はこれをLinuxで実行し、最新バージョンのgccを使用しましたありがとうございます

4

3 に答える 3

2

Linuxカーネルが「新しい」メモリページをプロセスのユーザースペースにマップするときはいつでも、このページをゼロで埋めるので、このメモリが属している可能性があるため、別のプロセスがそれらのメモリアドレスに残した可能性のあるデータの残りを見つけることができません。パスワードやキーなどの秘密のデータを使用する別のプロセス(および別のユーザー)(興味がある場合は、カーネルがlinux / gfp.hunsigned long get_zeroed_page(gfp_t gfp_mask);で定義された関数を呼び出します)

このページがプロセスに関連付けられている限り、ページを再びゼロで埋める努力は行われません。したがって、次のコードは、メモリを解放した場合でも、前に配置した値を出力する必要があります。

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


int main(){
    char* test1 = malloc(100);
    int i;
    for(i=0; i<5; i++){
        test1[i] = i+'A';
    }
    free(test1);
    char* test2 = malloc(100);
    for(i=0; i<5; i++){
        printf("%c.\n",test2[i]);
    }
    return 0;
}

これにより、次の出力が得られます(ただし保証はありません)。

$ ./a.out 
A.
B.
C.
D.
E.
于 2012-06-03T04:00:35.660 に答える
1

まだ初期化されていません。有用なものを表示する前に、値に設定する必要があります。(いくつかのコンパイラオプションが設定されていない限り)そのメモリアドレスにすでにあるものを単に出力しました。これはおそらく0です。

于 2012-06-03T02:39:45.757 に答える
0

配列を読み取っている場合、動作は未定義のままである必要があります。結果は、メモリが割り当てられる前に「\0」が格納されていたことを意味します。calloc()を使用して、配列をゼロに初期化します。

于 2012-06-03T02:47:32.507 に答える