std :: map :: size()与迭代器不同

时间:2012-10-29 10:45:43

标签: c++ memory stl iterator stdmap

我使用带有自定义比较类的std :: map和自定义类作为键

现在我使用operator []按键访问元素。然而,这似乎造成了一个大问题。地图似乎错误地分配元素或它们变得腐败。这很明显,因为我的自定义比较类在检测到它所比较的​​对象之一具有存储在其数据字段中的任意值时会引发异常(这似乎意味着构造函数没有运行或者对象从未在第一名)

现在又出现了另一个差异:

当我调用std :: map :: size()并将它与我可以递增begin()迭代器以获取end()迭代器然后它们不匹配的次数进行比较时。

具体而言,地图报告的尺寸()大于显然包含的尺寸。

我用作键的类是带有数据字段的自定义矩阵类:

unsigned int
unsigned int
vector<vector<Another Class>>

然而,在这些类中没有一个我使用指针算法或其他任何可以直接操作内存的东西。此外,我在任何使用的类中都没有自定义的复制构造函数。

编辑:比较功能

struct SymModMatComp
{
  bool operator()(const ModMat& mat1, const ModMat& mat2) const
  {
    unsigned int rows = mat1.get_row_number();

    unsigned int columns = mat1.get_column_number();
    if(mat2.get_row_number() != rows || mat2.get_column_number() != columns)
    {
      throw dimension_mismatch();
    }
    for(unsigned int i = 0; i < rows; i++)
    {
      for(unsigned int j = 0; j < columns; j++)
      {
        if(mat1.get_item(i,j).get_value() < mat2.get_item(i,j).get_value())
        {
          return true;
        }
        else if(mat1.get_item(i,j).get_value() > mat2.get_item(i,j).get_value())
        {
          return false;
        }
      }
    }
    return false;
  }
}

get_value()返回unsigned int

解决:

我使用valgrind来检查是否有任何内存访问错误......我发现程序中的一个完全不相关的部分确实对已经删除的对象进行了一遍又一遍的删除....

这似乎破坏了地图存储物品的空间。

感谢所有好主意!

2 个答案:

答案 0 :(得分:1)

没有代码就很难猜到,但无论如何我都会尝试。

你知道吗T& operator[] ( const key_type& x );如果键不存在,请在地图中插入值?因此,如果您已经没有地图中的密钥,地图大小将增加1。

将使用默认构造函数创建元素。

答案 1 :(得分:0)

如果您遇到带有复杂用户定义键的map的损坏,则您的比较功能可能不符合strict weak ordering的要求:

  • irreflexivity:!(x < x)
  • 不对称:!(x < y && y < x)
  • 传递性:x < y && y < z -> x < z
  • 无比的传递性:!(x < y || y < x || y < z || z < y) -> !(x < z || z < x)

如果不满足任何这些要求,将导致未定义的行为(例如内存损坏)。

如果矩阵参与比较函数,确保严格弱序的简单方法是在元素上使用词典排序。