• ベストアンサー

CRCの計算でエラー

VisualC++2008でプログラミングしております。簡単なモデムプログラムを作っているのですが、エラー検出で利用するCRCでつまづいています。具体的には、特定のファイルを送信しようとすると常にエラーが発生したと判断され、再送要求をし続けてしまいます。 以前、チェックサムでXORを利用した時も同様なことが発生したので、XORの計算があやしいのかなと感じています。デバッグでは正しく計算されるようなのですが、リリースで実行すると上記のようになります。 どなたかアドバイスを頂ければと思います。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

>また,特定のファイルを転送しようとしたときのみこの症状が出ます.そしていつも同じ場所でとまってしまいます.(例:13,447バイトのJPEGファイルを転送しようとすると,2816バイトまでしか転送されない)デバッグではその場所でエラーが出たりすることはありませんでした. であれば、データを転送する際に、128バイトのデータと、計算したCRCを画面かログファイルに出力してみてはどうでしょう。デバッグとリリースで同じ値になっているかどうか確認できると思います。 果たしてエラーの原因がCRCの計算にあるのか、それとも別の場所にあるのか、まずは絞り込むことが肝心かと思います。

zero-enna
質問者

お礼

回答を頂きありがとうございました.調査の結果,原因はCRCの計算ではないということが分かったので,締め切らせてもらいました. 送信側ではデータ128バイトプラスCRC2バイトの130バイト送信しているのですが,受信側で特定のデータブロックのときのみ129バイトしか受信されていませんでした.なぜかCRCの下位ビットが切れてしまうのです.これはこれで疑問なのですが,この質問とは関係なくなるのでここで終了とさせてもらいます. 私の調査不足が招いたことですが,ご回答を頂きありがとうございました.

その他の回答 (3)

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

変数の初期化忘れとかの可能性が高いように見受けられます。 C/C++の規格上は、宣言だけして値を代入していない変数には、 どんな数値が格納されているのかは不定です。 そのため、変数を使用する前には何らかの値を代入して必ず初期化しなければなりません。 ところが、 VisualC++ は、デバッグモードでは、明示的に初期化していない変数も0で初期化してくれます。 そのため、初期化していない変数に0が入ってるつもりで処理してたりすると、 デバッグモードではちゃんと動くがリリースモードではちゃんと動かない、 ということになります。

zero-enna
質問者

お礼

回答を頂きありがとうございました.調査の結果,原因はCRCの計算ではないということが分かったので,締め切らせてもらいました. 送信側ではデータ128バイトプラスCRC2バイトの130バイト送信しているのですが,受信側で特定のデータブロックのときのみ129バイトしか受信されていませんでした.なぜかCRCの下位ビットが切れてしまうのです.これはこれで疑問なのですが,この質問とは関係なくなるのでここで終了とさせてもらいます. 私の調査不足が招いたことですが,ご回答を頂きありがとうございました.

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

>どなたかアドバイスを頂ければと思います。よろしくお願いします。 ソースを見ないことにはなんともいえません。 通常、デバッグで動いてリリースで動かないのは、プログラムにバグがあるからです。コンパイラの問題であることは非常に稀です。 仮にコンパイラの問題だとしても、ソースがないことにはなんともいえないのは一緒です。

zero-enna
質問者

補足

vData:CRCを計算する8ビット(unsigned char) vCRC:CRC(unsigned short) 1データブロックは128バイトでそのお尻に2バイトのCRCを連結します. pszBuf:受信バッファ. vData = 0; vCRC = 0; for(int buff_num = 0; buff_num < 128; buff_num++){ vData = pszBuf[buff_num]; for(loop = 0; loop < 8; loop++){ // CRCを1バイト計算 // CRC計算変数がシフトで桁あふれするか確認 if((vCRC & 0x8000) != 0){ // 桁あふれあり vCRC = vCRC << 1; // CRC計算変数1ビットシフト vCRC = vCRC ^ 0x1021; // 生成多項式のXOR }else{ // 桁あふれなし vCRC = vCRC << 1; // CRC計算変数1ビットシフト } // データ変数がシフトで桁あふれするか確認 if((vData & 0x80) != 0){ // 桁あふれあり vData = vData << 1; // データ変数1ビットシフト vCRC = vCRC ^ 0x0001; // CRC計算変数に1XOR }else{ // 桁あふれなし vData = vData << 1; // データ変数1ビットシフト } } } また,特定のファイルを転送しようとしたときのみこの症状が出ます.そしていつも同じ場所でとまってしまいます.(例:13,447バイトのJPEGファイルを転送しようとすると,2816バイトまでしか転送されない)デバッグではその場所でエラーが出たりすることはありませんでした.

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.1

 一般的にはデバッグで動作OK,リリースでNGとなるのは潜在的なバグがあります。デバッグ版ではたまたま動いているように見えているだけです。  例えば初期化していない変数を使っているとか,宣言した配列をはみ出して読み書きしているとか考えられます。  また,XORの計算に不安があるのであれば,ソースの一部でも抜粋して補足資料として付けてもらえば詳細なアドバイスがもらえると思います。  既に行っているかもしれませんが,コンパイラのワーニング(警告)レベルをあげて,コンパイラからワーニングを出させ,コードの問題点がないか確認します。基本はワーニング0件を目指します。

zero-enna
質問者

お礼

回答を頂きありがとうございました.調査の結果,原因はCRCの計算ではないということが分かったので,締め切らせてもらいました. 送信側ではデータ128バイトプラスCRC2バイトの130バイト送信しているのですが,受信側で特定のデータブロックのときのみ129バイトしか受信されていませんでした.なぜかCRCの下位ビットが切れてしまうのです.これはこれで疑問なのですが,この質問とは関係なくなるのでここで終了とさせてもらいます. 私の調査不足が招いたことですが,ご回答を頂きありがとうございました.

zero-enna
質問者

補足

vData:CRCを計算する8ビット(unsigned char) vCRC:CRC(unsigned short) 1データブロックは128バイトでそのお尻に2バイトのCRCを連結します. pszBuf:受信バッファ. vData = 0; vCRC = 0; for(int buff_num = 0; buff_num < 128; buff_num++){ vData = pszBuf[buff_num]; for(loop = 0; loop < 8; loop++){ // CRCを1バイト計算 // CRC計算変数がシフトで桁あふれするか確認 if((vCRC & 0x8000) != 0){ // 桁あふれあり vCRC = vCRC << 1; // CRC計算変数1ビットシフト vCRC = vCRC ^ 0x1021; // 生成多項式のXOR }else{ // 桁あふれなし vCRC = vCRC << 1; // CRC計算変数1ビットシフト } // データ変数がシフトで桁あふれするか確認 if((vData & 0x80) != 0){ // 桁あふれあり vData = vData << 1; // データ変数1ビットシフト vCRC = vCRC ^ 0x0001; // CRC計算変数に1XOR }else{ // 桁あふれなし vData = vData << 1; // データ変数1ビットシフト } } } また,特定のファイルを転送しようとしたときのみこの症状が出ます.そしていつも同じ場所でとまってしまいます.(例:13,447バイトのJPEGファイルを転送しようとすると,2816バイトまでしか転送されない)デバッグではその場所でエラーが出たりすることはありませんでした.

関連するQ&A