在重构一些旧代码时,内部开发的繁琐的多级 map 被 std::undordered_multiset
取代。 。
多级 map 类似于 [string_key1,string_val]
。应用复杂的算法从 string_val
派生 key 并导致重复 string_val
存储在 map 中但具有不同的键。
最终在应用程序的某个时刻,迭代多层映射以获得 string_val
及其出现次数。
它取代的是 std::unordered_multilevelset
和string_val
刚刚插入其中。这似乎比拥有 std::map<std::string,int>
简单得多。并为每次插入检查-检索-更新计数器。
我想要检索其插入元素的出现次数,但我事先没有键。因此,我迭代了存储桶,但我的程序在创建字符串时崩溃了。
// hash map declaration
std::unordered_multiset<std::string> clevel;
// get element and occurences
for (size_t cbucket = clevel->bucket_count() - 1; cbucket != 0; --cbucket)
{
std::string cmsg(*clevel->begin(cbucket));
cmsg += t_str("times=") + \
std::to_string(clevel->bucket_size(cbucket));
}
我不明白这里发生了什么,试图调试它,但我不知何故堆栈(溢出?):)。程序崩溃于std::string cmsg(*it);
最佳答案
您应该考虑multiset
实际上如何作为哈希表工作。例如阅读此introduction您应该注意到, HashMap 实际上预先分配了其内部存储桶,并且存储桶的数量得到了优化。
因此,如果您插入元素“hello”,您可能会得到许多已创建的存储桶,但只有与 hash("hello")
对应的存储桶实际上才会有一个您可以使用的元素取消引用。其余的可以说是无效的。
取消引用迭代器到每个存储桶的开头会产生 SEGV,这就是您的情况。
要解决这种情况,您应该检查每次开始是否超过结束。
for (size_t cbucket = clevel->bucket_count() - 1; cbucket != 0; --cbucket)
{
auto it = clevel->begin(cbucket);
if (it != clevel->end(cbucket))
{
std::string cmsg(*it);
cmsg += t_str("times=") + \
std::to_string(clevel->bucket_size(cbucket));
}
}
关于c++ - 从 unordered_multiset 读取会导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34353929/