1

ポインターダウンキャスト

    int* ptrInt;
    char * ptrChar;
    void* ptrVoid;
    unsigned char indx;
    int sample = 0x12345678;

    ptrInt = &sample;
    ptrVoid = (void *)(ptrInt);
    ptrChar = (char *)(ptrVoid);

    /*manipulating ptrChar */
    for (indx = 0; indx < 4; indx++)
    {
        printf ("\n Value: %x \t Address: %p", *(ptrChar + indx), ( ptrChar + indx)); 
    }

出力:

 Value: 00000078         Address: 0022FF74
 Value: 00000056         Address: 0022FF75
 Value: 00000034         Address: 0022FF76
 Value: 00000012         Address: 0022FF77

質問: サンプルが char サイズのデータ​​に分割されたのはなぜですか? また、ポインター演算が実行された場合、どのようにして残りの値を取得できたのでしょうか? これはどのように可能でしたか?


ポインターのアップキャスト

unsigned int * ptrUint;
void * ptrVoid;
unsigned char sample = 0x08;

ptrVoid = (void *)&sample;
ptrUint = (unsigned int *) ptrVoid;

printf(" \n &sample: %p \t ptrUint: %p ", &sample, ptrUint );
printf(" \n sample: %p \t *ptrUint: %p ", sample, *ptrUint );  

出力:

 &sample: 0022FF6F       ptrUint: 0022FF6F
 sample: 00000008        *ptrUint: 22FF6F08    <- Problem Point

質問: *ptrUint にガベージ値があるのはなぜですか? ガベージ値が ptrUint に似ているのはなぜですか? このガベージ値を回避するには、malloc() または calloc() を使用する必要がありますか? ガベージ値を削除するには、どのような救済策を提案しますか?

4

3 に答える 3

1

最初の例では、char ポインターを使用しているため、データは一度に 1 バイトずつアクセスされます。メモリはバイト アドレス指定可能であるため、ポインタに 1 を追加すると、次に高いメモリ アドレスにアクセスします。これが for ループで起こっていることです。バイト ポインタを使用すると、コンパイラは 1 バイトのみにアクセスするように指示され、残りのビットは %p で印刷するときに 0 として表示されます。

2 番目の例では、サンプル バイトに 1 バイトが割り当てられ、次の 4 バイトが ptrUint に割り当てられていると思います。したがって、sample のメモリ アドレスから始まる値を取得し、それを 4 バイト ポインターに変換すると、Sample の値と ptrUint の最初の 3 バイトが表示されます。これを char ポインターにキャストして印刷すると、出力には 8 しか表示されません。

于 2011-07-03T07:29:38.483 に答える
0

他の答えは、あなたが見ているものを見ている理由をすでに説明しています。

2番目の例はundefined behaviorに依存していることを追加します。int *元々 ではなかったデータを指す を逆参照することは有効ではありませんint。すなわち:

char x = 5;
int *p = (int *)&x;
printf("%d\n", *p);  // undefined behaviour
于 2011-07-03T11:07:08.570 に答える
0

これらは、ある種の継承階層を意味するアップキャストやダウンキャストではありません。

最初の例では、整数へのポインターを、char(s) へのポインターのように扱います。int へのポインターをインクリメントすると 4 が加算され、char へのポインターをインクリメントすると 1 が加算されます (32 ビットの int と 8 ビットの char を想定)。それらを逆参照すると、それぞれ int と char が作成されます。したがって、バイトへの断片化。

2 番目の例では、sample という unsigned char 変数を int へのポインターのように扱い、逆参照します。基本的に、0x08 メモリ アドレスからガベージを読み取っています。& を忘れたとします。また、4 + 4 バイトの代わりに 1 バイトの char と 4 バイトの int を 2 番目の printf に渡しているため、printf が台無しになり、スタックから 3 バイト多く読み取られます。偶然にも、これは printf の最初の呼び出しに与えられた ptrUint 値の一部です。%p の代わりに %c を使用すると修正されます。

于 2011-07-03T07:48:13.710 に答える