I am using stl map to store flow information extracted from pcap files. When a packet comes, I use map.find to find if the flow the packet belongs to exist. I have to use map.find twice since the packet from A to B and the packet from B to A belongs to the same flow.
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;
};
The FiveTuple identifies a flow. I use the FiveTuple as the key element in map.
map is map< FiveTuple, Flow, FlowCmp>, where FlowCmp is a struct using memcmp to see if FiveTuple a is less than FiveTuple b, just like operator<.
To find whether the flow of the packet exists, I wrote code as follows where m is the name of the map and five_tuple is a FiveTuple with information extracted from the packet:
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
}
}
In the debug version in vs2010, the result is reasonable. When I changed it to the release version, I found that instead of returning the right iterator, the second m.find just gave me m.end most of the time. And I found that there are no initialization problems. How to fix the release version problem?
Seems like you are doing memcmp() on FiveTuple objects. That is undefined behaviour because FiveTuple contains trailing garbage bytes. These trailing garbage bytes are different in the debug version and the release version, so you get different results. You should rewrite FlowCmp so that it doesn’t use memcmp().
This is a guess based on the limited information provided, but if you want to test it out try
cout << sizeof(FiveTuple);. I bet you’ll see thatsizeof(FiveTuple) > sizeof(short) + sizeof(short) + sizeof(int) + sizeof(int) + sizeof(char). In other words there’s garbage in your struct and you shouldn’t use memcmp.Of course memcmp is bad for another reason because it means your code will be non-portable because it’s behaviour will depend on the endianess of your platform. That in itself is good enough reason not to use memcmp for this purpose.