【问题标题】:How unordered_map cause sigsegv [closed]unordered_map 如何导致 sigsegv [关闭]
【发布时间】:2012-01-07 22:07:11
【问题描述】:

编辑:解决了,我知道怎么做,但我不明白为什么。

我将variables声明从

tr1::unordered_map<int,T> variables;

unordered_map<int,T> variables;

它工作正常。

如果你知道原因,请将其写在答案中。

我有一个非常大的程序,所以我不知道我应该把哪个代码带到这里。

有抽象类,继承派生类。 摘要有unordered_map&lt;int,int&gt;(模板)作为私有成员,公共方法insert(int,int)

派生类使用基类insert方法向unordered_map&lt;int,int&gt;容器中插入元素,

第一个 int 使用 like 计数器并从 0 开始。前 11 个插入元素正常。但在第 12 个元素中,我得到了 sigsegv,并且在 stl_function.h(209) 处的 struct equal_to 出现故障。

在调试器中我看到 unordered_map 的 bucket_count 等于 11,这可能是一些线索。

我的编译器是 gcc 4.6.1。

也许您可以概括地写出什么可以unordered_map.insert 中导致 sigsegv?

谢谢你,对不起我的英语不好。

我会带上具体的代码,如果我知道的话。

编辑: 这是insert 方法:

virtual void Insert(int arrayPlace, T value)
{
    if (!isReadOnly)
    {            
        if (IsValueDataValid(value))
        {
           variables[arrayPlace] = value;
        }
        else
        {
            throw 2;
        }            
    }
    else
    {
        throw 4;
    }
};

声明是:

tr1::unordered_map<int,T> variables;

sigsegv 发生在 arrayPlace==11 时,而 value 是否相等并不重要。

【问题讨论】:

  • 您错误地使用了容器,但没有导致问题的代码,没有人可以回答这个问题。如果有很多代码,请开始将问题减少到重现问题所需的最低限度。
  • 假设it's always your fault 除非你能证明不是这样。
  • 错误出现在您的代码中的其他地方。这样的无序地图没有任何问题。

标签: c++ segmentation-fault unordered-map


【解决方案1】:

问题的答案很简单:如果正确使用代码,std::unordered_map不会造成分段错误!那么问题就变成了:使用std::unordered_map 时典型的用户错误是什么?我会立即想到三个问题:

  1. 对象作为值放置到地图中。也就是说,对象需要是可复制的或可移动的。也就是说,我会调查你得到的类型 T 是否正确实现了复制构造。特别是,如果复制构造函数不在类中,但该类有赋值运算符或析构函数,您需要特别注意它。
  2. 计算的散列键并不是真正的散列键,而是可能取决于对象的位置。这会导致有趣的行为,因为对象会移动到一定程度(尽管一旦插入它们就会保持原位)。
  3. 与上一期类似,相等运算并不是真正的相等运算。无序映射需要相等运算符来判断具有相同哈希码的两个对象是否确实相同。

鉴于密钥是int 并且提供了哈希码和相等性,我将专注于第一个问题。也就是说,一旦我证明std::unordered_map 的使用确实是问题所在,我就会专注于这一点:分割违规也可能很容易因为之前的事情被搞砸而导致。例如,某些东西可能以错误的方式覆盖了内存或删除了内存等。purify 或 valgrind 等工具可以帮助找到这些问题。在任何情况下,您都希望将程序简化为一个最小的崩溃示例。通常我会发现问题在这个过程中变得很明显。

【讨论】:

  • 你的意思是即使是简单的 int 变量(输入的)也需要复制构造函数(或对存在变量的引用)才能与 std::unordered_map 正常工作?
  • 嗯,从概念上讲,是的。但是,内置类型已[隐式]定义了所有相关操作。同样,为它们定义了一个工作哈希和相等性。如果T 类型也恰好是int,则问题不是与您发布的代码有关,而是在其他地方。真正导致问题的原因更难检测。根据您的错误描述,我会假设内存在某处被覆盖,但它可能完全是其他东西。问题出现在 `std::unordered_map' 只是偶然。
  • 所以不可能是因为T value在方法结束时超出了范围?
  • 否:标准 C++ 库中的所有容器都会保留您给它们的值的副本。如果你 T 是一个指针或一个类类型,它包含例如一个指针,您最终可能会在容器中使用过时的指针。但是,您说Tint
  • 好吧,它仍然是int。谢谢,现在我得想想……
猜你喜欢
  • 2010-11-29
  • 2017-11-09
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 2016-06-06
  • 2014-10-22
  • 1970-01-01
  • 2014-04-26
相关资源
最近更新 更多