4

pcap ファイルから抽出したフロー情報を保存するために stl マップを使用しています。パケットが来ると、map.find を使用して、パケットが属するフローが存在するかどうかを調べます。A から B へのパケットと B から A へのパケットは同じフローに属しているため、map.find を 2 回使用する必要があります。

struct FiveTuple
{
unsigned short source_port;
unsigned short dest_port;
unsigned int source_ip_addr;
unsigned int dest_ip_addr;
unsigned char transport_proto_type;
};

FiveTuple はフローを識別します。マップのキー要素として FiveTuple を使用します。

map は map< FiveTuple, Flow, FlowCmp> です。FlowCmp は memcmp を使用して、operator< のように、FiveTuple a が FiveTuple b より小さいかどうかを確認する構造体です。パケットのフローが存在するかどうかを確認するために、次のようなコードを記述しました。ここで、m はマップの名前、five_tuple はパケットから抽出された情報を含む FiveTuple です。

auto it = m.find(five_tuple);
if( it == m.end())
{
     //swap source and dest ip/port in five_tuple,
    it = m.find(five_tuple);

    if(it == m.end())
    {
          //do something
    }
}

vs2010 のデバッグ バージョンでは、結果は妥当です。これをリリース バージョンに変更したところ、ほとんどの場合、2 番目の m.find が正しいイテレータを返す代わりに m.end を返すだけであることがわかりました。そして、初期化の問題がないことがわかりました。リリース バージョンの問題を修正するにはどうすればよいですか?

4

1 に答える 1

5

FiveTuple オブジェクトで memcmp() を実行しているようです。FiveTuple には末尾のガベージ バイトが含まれているため、これは未定義の動作です。これらの末尾のガベージ バイトは、デバッグ バージョンとリリース バージョンで異なるため、異なる結果が得られます。memcmp() を使用しないように FlowCmp を書き直す必要があります。

これは提供された限られた情報に基づく推測ですが、試してみたい場合は試してみてくださいcout << sizeof(FiveTuple);。私はあなたがそれを見るに違いないsizeof(FiveTuple) > sizeof(short) + sizeof(short) + sizeof(int) + sizeof(int) + sizeof(char)。つまり、構造体にガベージがあり、memcmp を使用しないでください。

もちろん、 memcmp は別の理由で悪いです。これは、コードの動作がプラットフォームのエンディアンに依存するため、コードが移植不能になることを意味するためです。それ自体が、この目的に memcmp を使用しない十分な理由です。

于 2012-10-19T06:43:16.510 に答える