5

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

我改变了variables声明

tr1::unordered_map<int,T> variables;

unordered_map<int,T> variables;

它工作正常。

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

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

有抽象类,它与派生类一起继承。摘要有unordered_map<int,int>(模板)作为私有成员和公共方法insert(int,int)

派生类使用基类insert方法向unordered_map<int,int>容器中插入元素,

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

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

我的编译器是 gcc 4.6.1。

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

谢谢你,对我糟糕的英语感到抱歉。

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

编辑:这是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相等无关。

4

1 回答 1

7

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

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

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

于 2012-01-07T22:50:53.870 回答