2016-07-24 3 views
0

このコードでは、ネットワーク上で131バイトのバッファを使用し、デコードされた値を構造体の要素に格納します最初の要素protocol_versionをバッファ内の要素に設定しましたが、バッファ内の最初の要素にprotocol_versionの値を設定できません。次のように構造体は次のとおりです。構造体の要素の値は、返される前に設定されていますが、返されるときには設定されません。

typedef struct { 
    short protocol_version; 
    char username[64]; 
    char verification_key[64]; 
    char unused; 
} player_identification; 

、コードはここにある:私はそれをプリントアウトする方法

player_identification *parse_player_identification(char *buffer) { 
    player_identification *pkt = malloc(sizeof(player_identification)); 
    pkt->protocol_version = buffer[0]; 
    printf("0x0%x\n", pkt->protocol_version); // THIS PRINTS OUT 0x07 WHICH IS CORRECT! 

    char buf[64]; 
    for(int i = 0; i < 64; i++) { 
      buf[i] = buffer[i + 1]; 
    } 
    buf[64] = 0; 
    strcpy(pkt->username, trim_whitespace(&buf)); 

    char buf2[64]; 
    for(int i = 0; i < 64; i++) { 
      buf2[i] = buffer[i + 1 + 64]; 
    } 
    buf2[64] = 0; 
    strcpy(pkt->verification_key, trim_whitespace(&buf2)); 

    pkt->unused = buffer[130]; 
    return pkt; 
} 

注意、それはbuffer[0]は常にしかしなることを一定値である0x07の値を出力します常に0x00です。 GDBでは、ポインタが0x00(null)であるため、メモリアドレスの内容を読み取ることができません。何か案は?

+0

あなたの関数の* end *でそのフィールドを確認しなかった理由はありますか?その関数からすべてのメモリバッファサーカスの行を削除し、 'protocol_version'代入だけを残します。結果を確認してください。それが正しければ、物事を元に戻してください。私の推測では、コピー中にあなたのキャラクターバッファーを過ぎてバージョンフィールドを上書きしています。そして、私たちは[最小、完全**、検証可能な例](https://stackoverflow.com/help/mcve)を提供していないので、推測はあなたが得るすべてのものです。 (これは、他の人が邪悪なことを学ぶための*ひどい*の質問になります)。 – WhozCraig

+0

@WhozCraigは、サーカスの文字列操作の両方をコメントした後、実際には 'protocol_version'を適切に設定しました。バージョンフィールドを上書きする可能性のある文字列関数の両方で何が問題になっていますか? – mhsjlw

+2

そして、btw、 'buf [64] = 0;'と 'buf2 [64] = 0;はどちらも*未定義の動作*を呼び出します。それらのバッファは、両方とも0..63までのサブスクリプト可能です。 – WhozCraig

答えて

1

これらの両方:

buf[64] = 0; 
.... 
buf2[64] = 0; 

未定義の動作を呼び出します。それらのバッファは、要素幅が64だけです。 CのサイズNのネイティブ配列は、0 ...(N-1)から添え字可能です。これらのステートメントはいずれも、それを越えて1つの要素を記述し、そこからプログラムの残りの動作は妖精に委ねられます。

関連する問題