stl map.find使用vs2010在调试和发布中执行不同的操作

时间:2012-10-19 06:28:15

标签: c++ dictionary stl

我正在使用stl map存储从pcap文件中提取的流信息。当数据包到来时,我使用map.find来查找数据包所属的流是否存在。我必须使用map.find两次,因为从A到B的数据包和从B到A的数据包属于同一个流程。

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作为地图中的关键元素。

地图是地图< FiveTuple,Flow,FlowCmp>,其中FlowCmp是一个结构,使用memcmp来查看FiveTuple a是否小于FiveTuple b,就像operator<。 为了查找数据包的流是否存在,我编写了如下代码,其中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的调试版中,结果是合理的。当我将它更改为发布版本时,我发现不是返回正确的迭代器,第二个m.find只是给了我大部分时间。我发现没有初始化问题。如何解决发布版本问题?

1 个答案:

答案 0 :(得分:5)

好像你在FiveTuple对象上做了memcmp()。这是未定义的行为,因为FiveTuple包含尾随垃圾字节。这些尾随垃圾字节在调试版本和发行版本中是不同的,因此您得到不同的结果。您应该重写FlowCmp,以便它不使用memcmp()。

这是基于所提供的有限信息的猜测,但如果您想测试它,请尝试cout << sizeof(FiveTuple);。我打赌你会看到sizeof(FiveTuple) > sizeof(short) + sizeof(short) + sizeof(int) + sizeof(int) + sizeof(char)。换句话说,你的结构中有垃圾,你不应该使用memcmp。

当然,memcmp的另一个原因是不好的,因为这意味着您的代码将是不可移植的,因为它的行为将取决于您的平台的 endianess 。这本身就足以让我们不为此目的使用memcmp。

相关问题