Stl map.find performs differently in debugging and release using vs2010

I use a stl card to store stream information extracted from pcap files. When a package arrives, I use map.find to determine if there is a stream to which the package belongs. I have to use map.find twice since the packet from A to B and the packet from B to A belong to the same stream.

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 defines the flow. I use FiveTuple as a key element on the map.

map - map <FiveTuple, Flow, FlowCmp> where FlowCmp is a structure using memcmp to see if FiveTuple a is smaller than FiveTuple b, like the <operator. To find out if a package stream exists, I wrote the code as follows, where m is the name of the map, and five_tuple is FiveTuple with information extracted from the package:

 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 of vs2010, the result is reasonable. When I changed it to the release version, I found that instead of returning the correct iterator, the second m.find just gave me m.end most of the time. And I found that there are no problems with initialization. How to fix version release issue?

+4
source share
1 answer

It looks like you are doing memcmp () on FiveTuple objects. This behavior is undefined because FiveTuple contains trash bytes. These final garbage bytes differ in the debug version and release version, so you get different results. You must rewrite FlowCmp so that it does not use memcmp ().

This assumption is based on limited information, but if you want to check it out, try cout << sizeof(FiveTuple); . I bet you will see that sizeof(FiveTuple) > sizeof(short) + sizeof(short) + sizeof(int) + sizeof(int) + sizeof(char) . In other words, there is garbage in your structure and you should not use memcmp.

Of course, memcmp is bad for another reason, because it means that your code will not be portable, because its behavior will depend on the endianess of your platform. This in itself is reason enough not to use memcmp for this purpose.

+5
source

Source: https://habr.com/ru/post/1440706/


All Articles