1

私はネイティブの FORTRAN プログラマーであるため、C の知識が不足していることをあらかじめお詫びします。バイナリ ファイルを取り込んで解析し、使用している Fortran プログラム用の数百のレコード (正確には 871) を含む入力ファイルに解析するデバッグ用の C コードが与えられました。問題は、これらの入力バイナリと関連する c コードが Windows 環境で作成されたことです。パーサーは、ファイルの最後に到達するまでバイナリを読み取ります。

SAGE_Lvl0_Packet GetNextPacket()
{     

   int i;
   SAGE_Lvl0_Packet  inpkt;
   WORD              rdbuf[128]; 
   memset(rdbuf,0,sizeof(rdbuf));
   fprintf(stdout,"Nbytes: %u\n",Nbytes);//returns 224
   if((i = fread(rdbuf,Nbytes,1,Fp)) != 1)
      FileEnd = 1;
   else      
    {         
       if(FileType == 0)
          memcpy(&(inpkt.CCSDS),rdbuf,Nbytes);                 
       else  
          memcpy(&inpkt,rdbuf,Nbytes);
       memcpy(&CurrentPacket,&inpkt,sizeof(inpkt));
    }
    return inpkt;
}

そのため、コードがパケット 872 に到達すると、このスニペットは FileEnd = 1 を返す必要があります。代わりに、パーサーはファイルの末尾 (近く) から大量のデータを読み取ろうとします。これは、プログラムがクラッシュする原因になると思います (少なくとも Fortran ではそうなります。メモリの次の部分の読み取りを開始するだけでしょうか?) 幸いなことに、コードには後でパーサーがクラッシュしないことをキャッチする CRC があります。 t は正しいデータを読み取り、正常に終了します。

この問題は、Windows バイナリのバイナリ バッファ サイズと値が Linux よりも大きい/異なることが原因であると想定しています。その場合、c または Linux で Windows のバイナリを Linux に変換する簡単な方法はありますか? 私の仮定が間違っている場合は、おそらくコードをもう少し調べる必要があります。ところで、WORD は unsigned short int で、SAGE_Lvl0_Packet は合計 106 WORD の 3 層構造です。

4

1 に答える 1

1

fread()ここでの最大の問題は、ファイルの終わりを示すとFileEndフラグが設定されても、関数が(無効な)ゼロ化されたパケットを返すことになることだと思います。特に堅牢な設計ではありません。発信者はFileEnd、返されたばかりのパケットを使用する前にチェックする必要があると思いますが、それは表示されていないため、誤った想定である可能性があります。

また、パケットがどのように見えるかわからないため、さまざまなmemcpy()呼び出しが正しいかどうかを判断することはできません。memcpy()おそらく212バイトの長さしかない構造に224バイトをコピーするように求められるという事実は非常に問題があります。

他にも問題がある可能性がありますが、それらは私が現在目にしている大きな問題です。

于 2012-09-20T20:14:27.917 に答える