c++ - 从 unordered_multiset 读取会导致崩溃

标签 c++ c++11 hashmap unordered

在重构一些旧代码时,内部开发的繁琐的多级 map 被 std::undordered_multiset 取代。 。

多级 map 类似于 [string_key1,string_val] 。应用复杂的算法从 string_val 派生 key 并导致重复 string_val存储在 map 中但具有不同的键。

最终在应用程序的某个时刻,迭代多层映射以获得 string_val及其出现次数。

它取代的是 std::unordered_multilevelsetstring_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/

相关文章:

c++ - 使用 move() 而不是 std::move() 有什么陷阱吗?

c++ 抛出 'std::length_error' 的实例

java - 使用 Java Streams 从 Nested List 和 Outer List 收集数据

java - 我正在使用 .hashCode() 创建哈希值。 Java 中是否有一个库可以执行双重哈希来解决冲突?

python - 无法从用 Python C API 构建的模块中调用方法

c++ - 将参数传递给函数指针

c++ - typedef 为模板模板的别名

c++ - 使用 std 或 boost 库的 C++ 中的 Qtimer 等效于什么?

c++ - 如何为范围分配器模型启用自定义容器

java - 如何统计彩票中每个开奖号码的金额并将其输出到列表中?