C++ std::map 不同的键寻址同一索引
C++ std::map different key addressing the same index
在进行重构时,我不知何故搞砸了我的代码,所以我使用的 std::map 停止正常工作。
我正在重新组装零碎的 IPv4 数据包。部分解析Packet
来了,如果它是数据包的片段,它就会变成Fragment
,它具有重新组装的功能。
...
if(packet.isIPv4() && packet.isFragment()){
auto keyForMap = packet.key();
auto it = fragments.find(keyForMap);
auto fragmentNotFound = fragments.end();
std::cout << "-----------------------" << std::endl;
std::cout << "Fragments len: " << fragments.size() << std::endl;
keyForMap.print();
if(it == fragmentNotFound){
std::cout << "Not Found" << std::endl;
fragments[keyForMap] = Fragment(packet);
} else {
std::cout << "Found" << std::endl;
fragments[keyForMap].add(packet);
/* reassembling function call and some processing */
}
}
}
...
使用的数据类型: IPv4
std::array<uchar_t, 4>
fragments
fragments_t &
fragments_t
std::map<FragmentCommon, Fragment>
struct FragmentCommon{
FragmentCommon(IPv4 ipsrc,
IPv4 ipdst,
uchar_t protocol,
uint16_t identification) : ip_src(ipsrc),
ip_dst(ipdst),
protocol(protocol),
identification(identification){};
void print(){
printf("key>%d.%d.%d.%d ", ip_src[0], ip_src[1], ip_src[2], ip_src[3]);
printf("%d.%d.%d.%d ", ip_dst[0], ip_dst[1], ip_dst[2], ip_dst[3]);
printf("%d %dn", protocol, identification);
};
IPv4 ip_src;
IPv4 ip_dst;
uchar_t protocol;
uint16_t identification;
};
static bool operator<(const struct FragmentCommon &lhs, const struct FragmentCommon &rhs){
return lhs.ip_dst < rhs.ip_dst &&
lhs.ip_src < rhs.ip_src &&
lhs.protocol < rhs.protocol &&
lhs.identification < rhs.identification;
}
这是我的代码给我的输出:
-----------------------
Fragments len: 0 // Correct (this is first fragment so nothing is in map)
key>192.168.1.3 192.168.1.4 6 1
Not Found // So it's added into map
-----------------------
Fragments len: 1 // Correct (1st fragment is in map)
key>192.168.1.5 192.168.1.6 6 1
Found // Not correct...keys are different
-----------------------
Fragments len: 1
key>192.168.1.5 192.168.1.6 6 1
Found
-----------------------
Fragments len: 1
key>192.168.1.5 192.168.1.6 6 1
Found
-----------------------
鉴于您在问题中发布和陈述的内容,由于IPv4
是一个std::array<uchar_t,4>
(我假设uchar_t
是unsigned char
的别名),您可以使用std::tie为FragmentCommon
定义operator <
。
在以"级联"方式处理要测试的多个值时,使用 std::tie
更简单且更不容易出错来定义严格-弱排序(std::map
键需要)。
#include <tuple>
//...
static bool operator < (const struct FragmentCommon &lhs, const struct FragmentCommon &rhs)
{
return std::tie(lhs.ip_dst, lhs.ip_src, lhs.protocol, lhs.identification) <
std::tie(rhs.ip_dst, rhs.ip_src, rhs.protocol, rhs.identification);
}
由于 std::array 定义了运算符<,因此在每个std::tie
中使用所有 4 个参数时,使用 std::tie
可以正常工作。
相关文章:
- 从结构寻址时,MMAP变量的行为很奇怪
- 字节真的是最小可寻址单元吗
- 具有两个间接寻址运算符 (C++) 的函数参数的用途
- imread() 仍然返回空垫子,尽管在 openCV 4.0.0 中寻址正确
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 如何像在 C++ 中处理数组一样对 .txt 文件中的字符进行寻址?
- C++11右值引用寻址
- 对堆栈增长和寻址的困惑
- C++ std::find() 寻址返回向量的类函数时的意外行为
- 间接寻址运算符如何返回带有运算符重载的指针地址
- Adafruit NeoPixel库在寻址超过7个LED灯条时不起作用
- 在模板 SFINAE 约束中使用间接寻址级别会导致硬错误
- 错误:使用索引寻址和 Clang 的指令的操作数无效
- 是否可以寻址另一个网络中的服务器/客户端套接字?(C++)
- C++中的字节寻址算法
- 指针声明和间接寻址之间的区别
- 仅在使用间接寻址时调用虚函数 — 经典的早期绑定问题?
- C++ std::map 不同的键寻址同一索引
- Valgrind 错误:系统调用参数 epoll_pwait(sigmask) 指向不可寻址的字节
- 内联lambda是否遭受与函数指针间接寻址相同的延迟